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