Patch to improve Samba write speeds on Linux ext3 with 3.2.x
Jeremy Allison
jra at samba.org
Wed Sep 16 11:44:44 MDT 2009
On Tue, Sep 15, 2009 at 11:49:07AM +0200, axel.weber at cbc.de wrote:
> Hi Jeremy,
>
> I wonder if you can help me out. I just applied your patch to 3.4.1.
> The compilation gets interrupted with this error message:
>
> Compiling param/loadparm.c
> param/loadparm.c:5558: error: conflicting types for 'lp_strict_allocate'
> include/proto.h:4175: error: previous declaration of 'lp_strict_allocate' was here
> The following command failed:
> gcc -I../lib/zlib -O -I. -I/usr/local/src/samba-3.4.1/source3 -I/usr/local/src/samba-3.4.1/source3/../lib/popt -I/usr/local/src/samba-3.4.1/source3/iniparser/src -Iinclude -I./include -I. -I. -I./../lib/replace -I./../lib/talloc -I./../lib/tevent -I./../lib/tdb/include -I./libaddns -I./librpc -I./.. -DHAVE_CONFIG_H -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -Iinclude -I./include -I. -I. -I./../lib/replace -I./../lib/talloc -I./../lib/tevent -I./../lib/tdb/include -I./libaddns -I./librpc -I./.. -I./../lib/popt -I/usr/local/src/samba-3.4.1/source3/lib -I.. -I../source4 -D_SAMBA_BUILD_=3 -D_SAMBA_BUILD_=3 -fPIC -c param/loadparm.c -o param/loadparm.o
> make: *** [param/loadparm.o] Error 1
>
> Or do you suppose to use a 3.2 variant?
Here is the patch forward ported to 3.4.1.
Jeremy.
-------------- next part --------------
diff -u -r source3-orig/include/local.h source3/include/local.h
--- source3-orig/include/local.h 2009-09-16 10:32:24.000000000 -0700
+++ source3/include/local.h 2009-09-16 10:32:33.000000000 -0700
@@ -256,4 +256,8 @@
/* Maximum size of RPC data we will accept for one call. */
#define MAX_RPC_DATA_SIZE (15*1024*1024)
+/* When strict allocate = partial, define the limit on how far
+ * ahead we will write. */
+#define STRICT_ALLOCATE_PARTIAL_LIMIT 0x200000
+
#endif
diff -u -r source3-orig/include/proto.h source3/include/proto.h
--- source3-orig/include/proto.h 2009-09-16 10:32:24.000000000 -0700
+++ source3/include/proto.h 2009-09-16 10:38:24.000000000 -0700
@@ -4172,7 +4172,7 @@
bool lp_widelinks(int );
bool lp_symlinks(int );
bool lp_syncalways(int );
-bool lp_strict_allocate(int );
+int lp_strict_allocate(int );
bool lp_strict_sync(int );
bool lp_map_system(int );
bool lp_delete_readonly(int );
@@ -7102,7 +7102,7 @@
SMB_OFF_T offset);
int vfs_allocate_file_space(files_struct *fsp, uint64_t len);
int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len);
-int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len);
+int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len, enum smb_strict_allocate_options sa_options);
SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n);
char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf);
int vfs_ChDir(connection_struct *conn, const char *path);
diff -u -r source3-orig/include/smb.h source3/include/smb.h
--- source3-orig/include/smb.h 2009-09-16 10:32:24.000000000 -0700
+++ source3/include/smb.h 2009-09-16 10:32:33.000000000 -0700
@@ -1935,4 +1935,10 @@
struct timespec create_time;
};
+enum smb_strict_allocate_options {
+ STRICT_ALLOCATE_OFF=0,
+ STRICT_ALLOCATE_ON=1,
+ STRICT_ALLOCATE_PARTIAL=2
+};
+
#endif /* _SMB_H */
diff -u -r source3-orig/modules/vfs_default.c source3/modules/vfs_default.c
--- source3-orig/modules/vfs_default.c 2009-09-16 10:32:22.000000000 -0700
+++ source3/modules/vfs_default.c 2009-09-16 10:32:33.000000000 -0700
@@ -836,10 +836,14 @@
SMB_STRUCT_STAT st;
char c = 0;
SMB_OFF_T currpos;
+ enum smb_strict_allocate_options sa_options = lp_strict_allocate(SNUM(fsp->conn));
START_PROFILE(syscall_ftruncate);
- if (lp_strict_allocate(SNUM(fsp->conn))) {
+ /* Only use allocation truncate if strict allocate
+ * is set "on", not off or partial.
+ */
+ if (sa_options == STRICT_ALLOCATE_ON) {
result = strict_allocate_ftruncate(handle, fsp, len);
END_PROFILE(syscall_ftruncate);
return result;
diff -u -r source3-orig/param/loadparm.c source3/param/loadparm.c
--- source3-orig/param/loadparm.c 2009-09-16 10:32:23.000000000 -0700
+++ source3/param/loadparm.c 2009-09-16 10:32:33.000000000 -0700
@@ -453,7 +453,7 @@
bool bWidelinks;
bool bSymlinks;
bool bSyncAlways;
- bool bStrictAllocate;
+ int iStrictAllocate;
bool bStrictSync;
char magic_char;
struct bitmap *copymap;
@@ -597,7 +597,7 @@
True, /* bWidelinks */
True, /* bSymlinks */
False, /* bSyncAlways */
- False, /* bStrictAllocate */
+ STRICT_ALLOCATE_OFF, /* iStrictAllocate */
False, /* bStrictSync */
'~', /* magic char */
NULL, /* copymap */
@@ -878,6 +878,21 @@
{-1, NULL}
};
+static const struct enum_list enum_strict_allocate[] = {
+ {STRICT_ALLOCATE_OFF, "No"},
+ {STRICT_ALLOCATE_OFF, "False"},
+ {STRICT_ALLOCATE_OFF, "0"},
+ {STRICT_ALLOCATE_OFF, "Off"},
+ {STRICT_ALLOCATE_OFF, "disabled"},
+ {STRICT_ALLOCATE_ON, "Yes"},
+ {STRICT_ALLOCATE_ON, "True"},
+ {STRICT_ALLOCATE_ON, "1"},
+ {STRICT_ALLOCATE_ON, "On"},
+ {STRICT_ALLOCATE_ON, "enabled"},
+ {STRICT_ALLOCATE_PARTIAL, "partial"},
+ {-1, NULL}
+};
+
/* Note: We do not initialise the defaults union - it is not allowed in ANSI C
*
* The FLAG_HIDE is explicit. Parameters set this way do NOT appear in any edit
@@ -2430,11 +2445,11 @@
},
{
.label = "strict allocate",
- .type = P_BOOL,
+ .type = P_ENUM,
.p_class = P_LOCAL,
- .ptr = &sDefault.bStrictAllocate,
+ .ptr = &sDefault.iStrictAllocate,
.special = NULL,
- .enum_list = NULL,
+ .enum_list = enum_strict_allocate,
.flags = FLAG_ADVANCED | FLAG_SHARE,
},
{
@@ -5540,7 +5555,7 @@
FN_LOCAL_BOOL(lp_widelinks, bWidelinks)
FN_LOCAL_BOOL(lp_symlinks, bSymlinks)
FN_LOCAL_BOOL(lp_syncalways, bSyncAlways)
-FN_LOCAL_BOOL(lp_strict_allocate, bStrictAllocate)
+FN_LOCAL_INTEGER(lp_strict_allocate, iStrictAllocate)
FN_LOCAL_BOOL(lp_strict_sync, bStrictSync)
FN_LOCAL_BOOL(lp_map_system, bMap_system)
FN_LOCAL_BOOL(lp_delete_readonly, bDeleteReadonly)
diff -u -r source3-orig/smbd/fileio.c source3/smbd/fileio.c
--- source3-orig/smbd/fileio.c 2009-09-16 10:31:39.000000000 -0700
+++ source3/smbd/fileio.c 2009-09-16 10:32:33.000000000 -0700
@@ -125,9 +125,10 @@
if (pos == -1) {
ret = vfs_write_data(req, fsp, data, n);
} else {
+ enum smb_strict_allocate_options sa_options = lp_strict_allocate(SNUM(fsp->conn));
fsp->fh->pos = pos;
- if (pos && lp_strict_allocate(SNUM(fsp->conn))) {
- if (vfs_fill_sparse(fsp, pos) == -1) {
+ if (pos && (sa_options != STRICT_ALLOCATE_OFF)) {
+ if (vfs_fill_sparse(fsp, pos, sa_options) == -1) {
return -1;
}
}
Only in source3/smbd: .fileio.c.swp
diff -u -r source3-orig/smbd/vfs.c source3/smbd/vfs.c
--- source3-orig/smbd/vfs.c 2009-09-16 10:31:39.000000000 -0700
+++ source3/smbd/vfs.c 2009-09-16 10:32:33.000000000 -0700
@@ -556,8 +556,9 @@
contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
- if (!lp_strict_allocate(SNUM(fsp->conn)))
+ if (lp_strict_allocate(SNUM(fsp->conn)) == STRICT_ALLOCATE_OFF) {
return 0;
+ }
len -= st.st_size;
len /= 1024; /* Len is now number of 1k blocks needed. */
@@ -613,7 +614,7 @@
#define SPARSE_BUF_WRITE_SIZE (32*1024)
-int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
+int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len, enum smb_strict_allocate_options sa_options)
{
int ret;
SMB_STRUCT_STAT st;
@@ -631,6 +632,14 @@
return 0;
}
+ /* If strict allocate is set to "partial", ignore all allocate
+ * retquests over the STRICT_ALLOCATE_PARTIAL_LIMIT. */
+
+ if ((sa_options == STRICT_ALLOCATE_PARTIAL) &&
+ (len - st.st_size > STRICT_ALLOCATE_PARTIAL_LIMIT)) {
+ return 0;
+ }
+
DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size)));
More information about the samba-technical
mailing list