[SCM] Samba Shared Repository - branch v3-6-test updated

Jeremy Allison jra at samba.org
Thu Dec 2 17:35:55 MST 2010


The branch, v3-6-test has been updated
       via  a88b89d Move posix_fallocate into the VFS where it belongs.
       via  6fb840d Fix bug #7835 - vfs_fill_sparse() doesn't use posix_fallocate when strict allocate is on
      from  6b836d7 s3-waf: more krb5 configure checks.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit a88b89dfc18b3cf4ab01441dfb0a12b33157eb6d
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Dec 2 16:25:59 2010 -0800

    Move posix_fallocate into the VFS where it belongs.
    
    Jeremy.
    (cherry picked from commit 5819a36aef030772f1e9da81655c1f911a10372c)

commit 6fb840ddeec3c5edd7060a6a96de6780c524a90d
Author: Jeremy Allison <jra at samba.org>
Date:   Thu Dec 2 15:38:36 2010 -0800

    Fix bug #7835 - vfs_fill_sparse() doesn't use posix_fallocate when strict allocate is on
    
    Tries posix_fallocate() and then falls back to old code.
    
    Jeremy.
    (cherry picked from commit de8ceb5364de86f9b016251201474f011c16f6cb)

-----------------------------------------------------------------------

Summary of changes:
 examples/VFS/skel_opaque.c          |    8 ++++++
 examples/VFS/skel_transparent.c     |    8 ++++++
 source3/include/smbprofile.h        |    4 +++
 source3/include/vfs.h               |   10 ++++++++
 source3/include/vfs_macros.h        |    5 ++++
 source3/modules/vfs_default.c       |   17 ++++++++++++-
 source3/modules/vfs_full_audit.c    |   17 ++++++++++++++
 source3/modules/vfs_streams_xattr.c |   26 ++++++++++++++++++++++
 source3/modules/vfs_time_audit.c    |   22 ++++++++++++++++++
 source3/profile/profile.c           |    1 +
 source3/smbd/vfs.c                  |   41 +++++++++++++++++++++++++++++++++-
 11 files changed, 155 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 42f4e48..40ee5e9 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -308,6 +308,13 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_
 	return -1;
 }
 
+static int skel_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+			SMB_OFF_T offset, SMB_OFF_T len)
+{
+	errno = ENOSYS;
+	return -1;
+}
+
 static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
 	errno = ENOSYS;
@@ -813,6 +820,7 @@ struct vfs_fn_pointers skel_transparent_fns = {
 	.getwd = skel_getwd,
 	.ntimes = skel_ntimes,
 	.ftruncate = skel_ftruncate,
+	.posix_fallocate = skel_posix_fallocate,
 	.lock = skel_lock,
 	.kernel_flock = skel_kernel_flock,
 	.linux_setlease = skel_linux_setlease,
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index 42e54a8..ca22a30 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -292,6 +292,13 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_OFF_
 	return SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset);
 }
 
+static int skel_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+			SMB_OFF_T offset,
+			SMB_OFF_T len)
+{
+	return SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+}
+
 static bool skel_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
 	return SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type);
@@ -757,6 +764,7 @@ struct vfs_fn_pointers skel_transparent_fns = {
 	.getwd = skel_getwd,
 	.ntimes = skel_ntimes,
 	.ftruncate = skel_ftruncate,
+	.posix_fallocate = skel_posix_fallocate,
 	.lock = skel_lock,
 	.kernel_flock = skel_kernel_flock,
 	.linux_setlease = skel_linux_setlease,
diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h
index 5015d2a..647bf17 100644
--- a/source3/include/smbprofile.h
+++ b/source3/include/smbprofile.h
@@ -179,6 +179,10 @@ enum profile_stats_values
 #define syscall_ftruncate_count __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, count)
 #define syscall_ftruncate_time __profile_stats_value(PR_VALUE_SYSCALL_FTRUNCATE, time)
 
+	PR_VALUE_SYSCALL_POSIX_FALLOCATE,
+#define syscall_posix_fallocate_count __profile_stats_value(PR_VALUE_SYSCALL_POSIX_FALLOCATE, count)
+#define syscall_posix_fallocate_time __profile_stats_value(PR_VALUE_SYSCALL_POSIX_FALLOCATE, time)
+
 	PR_VALUE_SYSCALL_FCNTL_LOCK,
 #define syscall_fcntl_lock_count __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, count)
 #define syscall_fcntl_lock_time __profile_stats_value(PR_VALUE_SYSCALL_FCNTL_LOCK, time)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 9121069..cb49a17 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -128,6 +128,8 @@
 /* Changed to version 28 - Add private_flags uint32_t to CREATE call. */
 /* Leave at 28 - not yet released. Change realpath to assume NULL and return a
 		 malloc'ed path. JRA. */
+/* Leave at 28 - not yet released. Move posix_fallocate into the VFS
+		where it belongs. JRA. */
 #define SMB_VFS_INTERFACE_VERSION 28
 
 
@@ -250,6 +252,10 @@ struct vfs_fn_pointers {
 		      const struct smb_filename *smb_fname,
 		      struct smb_file_time *ft);
 	int (*ftruncate)(struct vfs_handle_struct *handle, struct files_struct *fsp, SMB_OFF_T offset);
+	int (*posix_fallocate)(struct vfs_handle_struct *handle,
+				struct files_struct *fsp,
+				SMB_OFF_T offset,
+				SMB_OFF_T len);
 	bool (*lock)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
 	int (*kernel_flock)(struct vfs_handle_struct *handle, struct files_struct *fsp,
 			    uint32 share_mode, uint32_t access_mask);
@@ -602,6 +608,10 @@ int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
 			struct smb_file_time *ft);
 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
 			   struct files_struct *fsp, SMB_OFF_T offset);
+int smb_vfs_call_posix_fallocate(struct vfs_handle_struct *handle,
+			struct files_struct *fsp,
+			SMB_OFF_T offset,
+			SMB_OFF_T len);
 bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
 		       struct files_struct *fsp, int op, SMB_OFF_T offset,
 		       SMB_OFF_T count, int type);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 5b38e64..2eedd2b 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -249,6 +249,11 @@
 #define SMB_VFS_NEXT_FTRUNCATE(handle, fsp, offset) \
 	smb_vfs_call_ftruncate((handle)->next, (fsp), (offset))
 
+#define SMB_VFS_POSIX_FALLOCATE(fsp, offset, len) \
+	smb_vfs_call_posix_fallocate((fsp)->conn->vfs_handles, (fsp), (offset), (len))
+#define SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len) \
+	smb_vfs_call_posix_fallocate((handle)->next, (fsp), (offset), (len))
+
 #define SMB_VFS_LOCK(fsp, op, offset, count, type) \
 	smb_vfs_call_lock((fsp)->conn->vfs_handles, (fsp), (op), (offset), (count), (type))
 #define SMB_VFS_NEXT_LOCK(handle, fsp, op, offset, count, type) \
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 977a563..63993fe 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -854,7 +854,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
 	   emulation is being done by the libc (like on AIX with JFS1). In that
 	   case we do our own emulation. posix_fallocate implementations can
 	   return ENOTSUP or EINVAL in cases like that. */
-	ret = sys_posix_fallocate(fsp->fh->fd, st.st_ex_size, space_to_write);
+	ret = SMB_VFS_POSIX_FALLOCATE(fsp, st.st_ex_size, space_to_write);
 	if (ret == ENOSPC) {
 		errno = ENOSPC;
 		return -1;
@@ -862,7 +862,7 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
 	if (ret == 0) {
 		return 0;
 	}
-	DEBUG(10,("strict_allocate_ftruncate: sys_posix_fallocate failed with "
+	DEBUG(10,("strict_allocate_ftruncate: SMB_VFS_POSIX_FALLOCATE failed with "
 		"error %d. Falling back to slow manual allocation\n", ret));
 
 	/* available disk space is enough or not? */
@@ -974,6 +974,19 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, SMB_O
 	return result;
 }
 
+static int vfswrap_posix_fallocate(vfs_handle_struct *handle,
+			files_struct *fsp,
+			SMB_OFF_T offset,
+			SMB_OFF_T len)
+{
+	int result;
+
+	START_PROFILE(syscall_posix_fallocate);
+	result = sys_posix_fallocate(fsp->fh->fd, offset, len);
+	END_PROFILE(syscall_posix_fallocate);
+	return result;
+}
+
 static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
 	bool result;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 3328128..b7c0888 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -124,6 +124,7 @@ typedef enum _vfs_op_type {
 	SMB_VFS_OP_GETWD,
 	SMB_VFS_OP_NTIMES,
 	SMB_VFS_OP_FTRUNCATE,
+	SMB_VFS_OP_POSIX_FALLOCATE,
 	SMB_VFS_OP_LOCK,
 	SMB_VFS_OP_KERNEL_FLOCK,
 	SMB_VFS_OP_LINUX_SETLEASE,
@@ -262,6 +263,7 @@ static struct {
 	{ SMB_VFS_OP_GETWD,	"getwd" },
 	{ SMB_VFS_OP_NTIMES,	"ntimes" },
 	{ SMB_VFS_OP_FTRUNCATE,	"ftruncate" },
+	{ SMB_VFS_OP_POSIX_FALLOCATE,"posix_fallocate" },
 	{ SMB_VFS_OP_LOCK,	"lock" },
 	{ SMB_VFS_OP_KERNEL_FLOCK,	"kernel_flock" },
 	{ SMB_VFS_OP_LINUX_SETLEASE, "linux_setlease" },
@@ -1222,6 +1224,20 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp
 	return result;
 }
 
+static int smb_full_audit_posix_fallocate(vfs_handle_struct *handle, files_struct *fsp,
+			   SMB_OFF_T offset,
+			   SMB_OFF_T len)
+{
+	int result;
+
+	result = SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+
+	do_log(SMB_VFS_OP_POSIX_FALLOCATE, (result >= 0), handle,
+	       "%s", fsp_str_do_log(fsp));
+
+	return result;
+}
+
 static bool smb_full_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
 		       int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
 {
@@ -2218,6 +2234,7 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
 	.getwd = smb_full_audit_getwd,
 	.ntimes = smb_full_audit_ntimes,
 	.ftruncate = smb_full_audit_ftruncate,
+	.posix_fallocate = smb_full_audit_posix_fallocate,
 	.lock = smb_full_audit_lock,
 	.kernel_flock = smb_full_audit_kernel_flock,
 	.linux_setlease = smb_full_audit_linux_setlease,
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index 218e5ec..8870c6e 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -1023,6 +1023,31 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
 	return 0;
 }
 
+static int streams_xattr_posix_fallocate(struct vfs_handle_struct *handle,
+					struct files_struct *fsp,
+					SMB_OFF_T offset,
+					SMB_OFF_T len)
+{
+        struct stream_io *sio =
+		(struct stream_io *)VFS_FETCH_FSP_EXTENSION(handle, fsp);
+
+	DEBUG(10, ("streams_xattr_posix_fallocate called for file %s offset %.0f"
+		"len = %.0f\n",
+		fsp_str_dbg(fsp), (double)offset, (double)len));
+
+	if (sio == NULL) {
+		return SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+	}
+
+	if (!streams_xattr_recheck(sio)) {
+		return -1;
+	}
+
+	/* Let the pwrite code path handle it. */
+	return ENOSYS;
+}
+
+
 static struct vfs_fn_pointers vfs_streams_xattr_fns = {
 	.fs_capabilities = streams_xattr_fs_capabilities,
 	.open = streams_xattr_open,
@@ -1034,6 +1059,7 @@ static struct vfs_fn_pointers vfs_streams_xattr_fns = {
 	.unlink = streams_xattr_unlink,
 	.rename = streams_xattr_rename,
         .ftruncate = streams_xattr_ftruncate,
+        .posix_fallocate = streams_xattr_posix_fallocate,
 	.streaminfo = streams_xattr_streaminfo,
 };
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index af4fd33..e9481b5 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -905,6 +905,27 @@ static int smb_time_audit_ftruncate(vfs_handle_struct *handle,
 	return result;
 }
 
+static int smb_time_audit_posix_fallocate(vfs_handle_struct *handle,
+				    files_struct *fsp,
+				    SMB_OFF_T offset,
+				    SMB_OFF_T len)
+{
+	int result;
+	struct timespec ts1,ts2;
+	double timediff;
+
+	clock_gettime_mono(&ts1);
+	result = SMB_VFS_NEXT_POSIX_FALLOCATE(handle, fsp, offset, len);
+	clock_gettime_mono(&ts2);
+	timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+	if (timediff > audit_timeout) {
+		smb_time_audit_log("posix_fallocate", timediff);
+	}
+
+	return result;
+}
+
 static bool smb_time_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
 				int op, SMB_OFF_T offset, SMB_OFF_T count,
 				int type)
@@ -2336,6 +2357,7 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
 	.getwd = smb_time_audit_getwd,
 	.ntimes = smb_time_audit_ntimes,
 	.ftruncate = smb_time_audit_ftruncate,
+	.posix_fallocate = smb_time_audit_posix_fallocate,
 	.lock = smb_time_audit_lock,
 	.kernel_flock = smb_time_audit_kernel_flock,
 	.linux_setlease = smb_time_audit_linux_setlease,
diff --git a/source3/profile/profile.c b/source3/profile/profile.c
index 59b409d..8013fc3 100644
--- a/source3/profile/profile.c
+++ b/source3/profile/profile.c
@@ -234,6 +234,7 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
 	    "syscall_getwd",		/* PR_VALUE_SYSCALL_GETWD */
 	    "syscall_ntimes",		/* PR_VALUE_SYSCALL_NTIMES */
 	    "syscall_ftruncate",	/* PR_VALUE_SYSCALL_FTRUNCATE */
+	    "syscall_posix_fallocate",	/* PR_VALUE_SYSCALL_POSIX_FALLOCATE */
 	    "syscall_fcntl_lock",	/* PR_VALUE_SYSCALL_FCNTL_LOCK */
 	    "syscall_kernel_flock",     /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
 	    "syscall_linux_setlease",   /* PR_VALUE_SYSCALL_LINUX_SETLEASE */
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 7042518..1829e3a 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -584,6 +584,12 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
 		return 0;
 	}
 
+#ifdef S_ISFIFO
+	if (S_ISFIFO(st.st_ex_mode)) {
+		return 0;
+	}
+#endif
+
 	DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to "
 		  "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp),
 		  (double)st.st_ex_size, (double)len,
@@ -593,6 +599,30 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
 
 	flush_write_cache(fsp, SIZECHANGE_FLUSH);
 
+	offset = st.st_ex_size;
+	num_to_write = len - st.st_ex_size;
+
+	/* Only do this on non-stream file handles. */
+	if (fsp->base_fsp == NULL) {
+		/* for allocation try posix_fallocate first. This can fail on some
+		 * platforms e.g. when the filesystem doesn't support it and no
+		 * emulation is being done by the libc (like on AIX with JFS1). In that
+		 * case we do our own emulation. posix_fallocate implementations can
+		 * return ENOTSUP or EINVAL in cases like that. */
+		ret = SMB_VFS_POSIX_FALLOCATE(fsp, offset, num_to_write);
+		if (ret == ENOSPC) {
+			errno = ENOSPC;
+			ret = -1;
+			goto out;
+		}
+		if (ret == 0) {
+			set_filelen_write_cache(fsp, len);
+			goto out;
+		}
+		DEBUG(10,("vfs_fill_sparse: SMB_VFS_POSIX_FALLOCATE failed with "
+			"error %d. Falling back to slow manual allocation\n", ret));
+	}
+
 	if (!sparse_buf) {
 		sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
 		if (!sparse_buf) {
@@ -602,8 +632,6 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len)
 		}
 	}
 
-	offset = st.st_ex_size;
-	num_to_write = len - st.st_ex_size;
 	total = 0;
 
 	while (total < num_to_write) {
@@ -1411,6 +1439,15 @@ int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
 	return handle->fns->ftruncate(handle, fsp, offset);
 }
 
+int smb_vfs_call_posix_fallocate(struct vfs_handle_struct *handle,
+				struct files_struct *fsp,
+				SMB_OFF_T offset,
+				SMB_OFF_T len)
+{
+	VFS_FIND(posix_fallocate);
+	return handle->fns->posix_fallocate(handle, fsp, offset, len);
+}
+
 int smb_vfs_call_kernel_flock(struct vfs_handle_struct *handle,
 			      struct files_struct *fsp, uint32 share_mode,
 			      uint32_t access_mask)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list