[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Dec 20 18:42:01 MST 2010


The branch, master has been updated
       via  8998f4b Added call out to a Linux-compatible fallocate() when we need to extend a file allocation extent without changing end-of-file size.
      from  09aea03 CREATE in a compound CREATE/NOTIFY sequence was being passed through set_operation_credits() twice (ultimately perhaps because of bug 7331 involving this compound sequence and the need to be ready for any incoming CANCEL of the NOTIFY). This had the server thinking it had granted more credit than it actually had, which lead to zero-credits being granted in interim NOTIFY responses.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 8998f4b01310e4b45e75d8d5f3260b5ba5c1cdf9
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Dec 20 16:53:16 2010 -0800

    Added call out to a Linux-compatible fallocate() when we need to extend a file
    allocation extent without changing end-of-file size.
    
    Autobuild-User: Jeremy Allison <jra at samba.org>
    Autobuild-Date: Tue Dec 21 02:41:24 CET 2010 on sn-devel-104

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

Summary of changes:
 source3/configure.in          |   35 +++++++++++++++++++++++++++++++++++
 source3/include/proto.h       |    1 +
 source3/lib/system.c          |   35 +++++++++++++++++++++++++++++++++++
 source3/modules/vfs_default.c |    5 +++--
 source3/smbd/vfs.c            |   13 ++++++++++++-
 5 files changed, 86 insertions(+), 3 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/configure.in b/source3/configure.in
index b43d0b3..ed99b17 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -741,6 +741,7 @@ AC_CHECK_HEADERS(sys/syslog.h syslog.h)
 AC_CHECK_HEADERS(langinfo.h locale.h)
 AC_CHECK_HEADERS(xfs/libxfs.h)
 AC_CHECK_HEADERS(netgroup.h)
+AC_CHECK_HEADERS(linux/falloc.h)
 
 AC_CHECK_HEADERS(rpcsvc/yp_prot.h,,,[[
 #if HAVE_RPC_RPC_H
@@ -1095,6 +1096,7 @@ AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetg
 AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf)
 AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf stat64 fstat64)
 AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt lseek64 ftruncate64 posix_fallocate posix_fallocate64)
+AC_CHECK_FUNCS(fallocate fallocate64)
 AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam)
 AC_CHECK_FUNCS(opendir64 readdir64 seekdir64 telldir64 rewinddir64 closedir64)
 AC_CHECK_FUNCS(getpwent_r)
@@ -2563,6 +2565,39 @@ fi
 fi
 # end utmp details
 
+AC_CACHE_CHECK([for linux fallocate],samba_cv_HAVE_LINUX_FALLOCATE,[
+AC_TRY_COMPILE([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#define _GNU_SOURCE
+#include <fcntl.h>
+#if defined(HAVE_LINUX_FALLOC_H)
+#include <linux/falloc.h>
+#endif],
+[int ret = fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 10);],
+samba_cv_HAVE_LINUX_FALLOCATE=yes,samba_cv_HAVE_LINUX_FALLOCATE=no)])
+if test x"$samba_cv_HAVE_LINUX_FALLOCATE" = x"yes" && test x"$ac_cv_func_fallocate" = x"yes"; then
+    AC_DEFINE(HAVE_LINUX_FALLOCATE,1,[Whether the Linux 'fallocate' function is available])
+fi
+
+AC_CACHE_CHECK([for linux fallocate64],samba_cv_HAVE_LINUX_FALLOCATE64,[
+AC_TRY_COMPILE([
+#if defined(HAVE_UNISTD_H)
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#define _GNU_SOURCE
+#include <fcntl.h>
+#if defined(HAVE_LINUX_FALLOC_H)
+#include <linux/falloc.h>
+#endif],
+[int ret = fallocate64(0, FALLOC_FL_KEEP_SIZE, 0, 10);],
+samba_cv_HAVE_LINUX_FALLOCATE64=yes,samba_cv_HAVE_LINUX_FALLOCATE64=no)])
+if test x"$samba_cv_HAVE_LINUX_FALLOCATE64" = x"yes" && test x"$ac_cv_func_fallocate64" = x"yes"; then
+    AC_DEFINE(HAVE_LINUX_FALLOCATE64,1,[Whether the Linux 'fallocate64' function is available])
+fi
 
 ICONV_LOOK_DIRS="/usr /usr/local /sw /opt"
 AC_ARG_WITH(libiconv,
diff --git a/source3/include/proto.h b/source3/include/proto.h
index dabb315..566b3f3 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -888,6 +888,7 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf,
 	      bool fake_dir_create_times);
 int sys_ftruncate(int fd, SMB_OFF_T offset);
 int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len);
+int sys_fallocate(int fd, enum vfs_fallocate_mode mode, SMB_OFF_T offset, SMB_OFF_T len);
 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence);
 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence);
 SMB_OFF_T sys_ftell(FILE *fp);
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 02322b7..4cf6a29 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -695,6 +695,41 @@ int sys_posix_fallocate(int fd, SMB_OFF_T offset, SMB_OFF_T len)
 }
 
 /*******************************************************************
+ An fallocate() function that matches the semantics of the Linux one.
+********************************************************************/
+
+#ifdef HAVE_LINUX_FALLOC_H
+#include <linux/falloc.h>
+#endif
+
+int sys_fallocate(int fd, enum vfs_fallocate_mode mode, SMB_OFF_T offset, SMB_OFF_T len)
+{
+#if defined(HAVE_LINUX_FALLOCATE64) || defined(HAVE_LINUX_FALLOCATE)
+	int lmode;
+	switch (mode) {
+	case VFS_FALLOCATE_EXTEND_SIZE:
+		lmode = 0;
+		break;
+	case VFS_FALLOCATE_KEEP_SIZE:
+		lmode = FALLOC_FL_KEEP_SIZE;
+		break;
+	default:
+		errno = EINVAL;
+		return -1;
+	}
+#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LINUX_FALLOCATE64)
+	return fallocate64(fd, lmode, offset, len);
+#elif defined(HAVE_LINUX_FALLOCATE)
+	return fallocate(fd, lmode, offset, len);
+#endif
+#else
+	/* TODO - plumb in fallocate from other filesysetms like VXFS etc. JRA. */
+	errno = ENOSYS;
+	return -1;
+#endif
+}
+
+/*******************************************************************
  An ftruncate() wrapper that will deal with 64 bit filesizes.
 ********************************************************************/
 
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index e08d48f..54f38c3 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -965,9 +965,10 @@ static int vfswrap_fallocate(vfs_handle_struct *handle,
 	START_PROFILE(syscall_fallocate);
 	if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
 		result = sys_posix_fallocate(fsp->fh->fd, offset, len);
+	} else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
+		result = sys_fallocate(fsp->fh->fd, mode, offset, len);
 	} else {
-		/* TODO - implement call into Linux fallocate call. */
-		errno = ENOSYS;
+		errno = EINVAL;
 		result = -1;
 	}
 	END_PROFILE(syscall_fallocate);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 2ebe2a1..802639f 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -501,13 +501,24 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t len)
 		return ret;
 	}
 
+	if (!lp_strict_allocate(SNUM(fsp->conn)))
+		return 0;
+
 	/* Grow - we need to test if we have enough space. */
 
 	contend_level2_oplocks_begin(fsp, LEVEL2_CONTEND_ALLOC_GROW);
+
+	/* See if we have a syscall that will allocate beyond end-of-file
+	   without changing EOF. */
+	ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_KEEP_SIZE, 0, len);
+
 	contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_ALLOC_GROW);
 
-	if (!lp_strict_allocate(SNUM(fsp->conn)))
+	if (ret == 0) {
+		/* We changed the allocation size on disk, but not
+		   EOF - exactly as required. We're done ! */
 		return 0;
+	}
 
 	len -= fsp->fsp_name->st.st_ex_size;
 	len /= 1024; /* Len is now number of 1k blocks needed. */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list