[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Mon Mar 9 17:03:06 MDT 2015


The branch, master has been updated
       via  95a6a89 torture/ioctl: add range overflow QAR test
       via  27e19a8 torture/ioctl: add multi-range QAR test
       via  2edb6dd torture/ioctl: add QAR off-by-one bug paranoia test
       via  e27ea1b torture/ioctl: test sparse file operation locking
       via  b0e5a4e s3/smbd: fix FSCTL_SET_SPARSE permission checks
       via  55d8ac5 torture/ioctl: add ioctl_sparse_perms test
       via  6729557 torture/ioctl: rework and reduce pattern helper IO sizes
       via  4dec434 torture/ioctl: add sparse_punch_invalid test
       via  81065a4 torture/ioctl: remove FS specific sparse copy-chunk expectations
       via  904d580 torture/ioctl: remove FS specific sparse punch check
       via  f5c472e torture/ioctl: remove 64K chunk size assumptions
       via  43e5811 s3/statvfs: expose FILE_SUPPORTS_SPARSE_FILES capability
       via  29531c5 smbd/ioctl: add FSCTL_QUERY_ALLOCATED_RANGES support
       via  76fff2b build: check for SEEK_HOLE and SEEK_DATA support
       via  b5a635f idl/ioctl: change QAR response array to a DATA_BLOB
       via  1359e85 smbd/ioctl: add FSCTL_SET_ZERO_DATA support
       via  47f15b1 system: add hole punch support to sys_fallocate()
       via  762f9cb build: check for fallocate hole-punch support
       via  12c0b6b s3/vfs: change fallocate mode flags from enum->uint32_t
       via  3787119 lib/system: remove useless HAVE_LINUX_FALLOCATE64 logic
      from  f5d0204 s3-winbind: Fix chached user group lookup of trusted domains.

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


- Log -----------------------------------------------------------------
commit 95a6a892d9f50aced3d67e7b79e5ca2401134c38
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Mar 9 16:21:24 2015 +0100

    torture/ioctl: add range overflow QAR test
    
    Issue a QAR request with an offset and length that generate an integer
    (uint64_t) overflow when summed together. This should result in an
    NT_STATUS_INVALID_PARAMETER response, as confirmed against Windows
    Server 2012 & 2008.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue Mar 10 00:02:18 CET 2015 on sn-devel-104

commit 27e19a81e6fae6ea072d865dcadebc9bb9db48c5
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Feb 26 01:13:58 2015 +0100

    torture/ioctl: add multi-range QAR test
    
    Write 10 x 64K ranges, with 64K holes punched in between. Afterwards,
    check that all ranges are present in the QAR response.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 2edb6ddc31e2a7382f8fcd8eaebde3392f85886f
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed Feb 25 19:23:49 2015 +0100

    torture/ioctl: add QAR off-by-one bug paranoia test
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit e27ea1bcbbf74ccf1bef224660a30b4468ad3fb3
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed Feb 25 15:29:56 2015 +0100

    torture/ioctl: test sparse file operation locking
    
    An exclusively locked file can still be marked sparse. QAR requests
    covering the locked-range should also succed. ZERO_DATA requests are
    blocked.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b0e5a4ebde8af4dad9fda0f73df23d55ee6d858a
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 23 20:27:37 2015 +0100

    s3/smbd: fix FSCTL_SET_SPARSE permission checks
    
    On Windows servers (tested against Windows Server 2008 & 2012) the
    FSCTL_SET_SPARSE ioctl is processed if FILE_WRITE_DATA,
    FILE_WRITE_ATTRIBUTES _or_ SEC_FILE_APPEND_DATA permissions are granted
    on the open file-handle.
    Fix Samba such that it matches this behaviour, rather than only checking
    for FILE_WRITE_DATA or FILE_WRITE_ATTRIBUTES.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 55d8ac528097013ee3c072406952e0394ce6ff34
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 23 20:24:11 2015 +0100

    torture/ioctl: add ioctl_sparse_perms test
    
    This test confirms that correct FSCTL_SET_SPARSE permission checks are
    in place on the server.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 6729557c2788f232dcc1e8b5f14ec1cadc962a35
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 23 20:03:19 2015 +0100

    torture/ioctl: rework and reduce pattern helper IO sizes
    
    check_pattern() currently attempts to read all data in one go. Fix it to
    use a 64K maximum IO size so that it works against Windows Server 2008.
    
    Additionally, rework write_pattern() so that it only allocates a buffer
    for the largest IO size (now 64K), rather than for the full write
    length.
    
    Finally, assert that callers are correctly performing pattern IO in
    8-byte increments - copy_chunk_tiny was not, so fix it.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 4dec434f7151e0ef222aa72531f3353ee2651c74
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 23 11:29:52 2015 +0100

    torture/ioctl: add sparse_punch_invalid test
    
    Attempt to extend a file using ZERO_DATA. The operation should succeed,
    but the file should not be extended, as specified in MS-FSCC <58>
    Section 2.3.65:
      This FSCTL sets the range of bytes to zero (0) without extending the
      file size.
    
    Also test zero length and invalid BFZ requests.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 81065a4801f70b4d9190bc2b351a08626e8df264
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 23 11:28:17 2015 +0100

    torture/ioctl: remove FS specific sparse copy-chunk expectations
    
    NTFS deallocates an entire file when a sparse zero-data request spans
    the full length. Other filesystems (e.g. EXT4 and Btrfs) do not.
    
    vfs_btrfs is additionally capable of preserving sparse regions for
    copy-chunk, using the BTRFS_IOC_CLONE_RANGE ioctl. This should not be
    treated as a failure.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 904d5809e588a898bfd9658eeb3c9b4bc63695f8
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 23 11:09:02 2015 +0100

    torture/ioctl: remove FS specific sparse punch check
    
    Samba uses PUNCH_HOLE to zero a range, and subsequently uses fallocate()
    to allocate the punched range if the file is marked non-sparse and
    "strict allocate" is enabled.
    
    In both cases, the zeroed range will not be detected by SEEK_DATA, so
    the range won't be present in QAR responses until the file is marked
    non-sparse again.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit f5c472ea47b2b45f8303e62772a21b77644ed5dc
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Feb 19 16:09:02 2015 +0100

    torture/ioctl: remove 64K chunk size assumptions
    
    These tests assumed that 4K chunks remain allocated following write at
    a subsequent offset. This is not the case for other filesystems (E.g.
    XFS, Btrfs, Etc.), which may deallocate the chunk.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 43e581188ab107e730ef0a232cc406963781bc5d
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Feb 19 16:46:56 2015 +0100

    s3/statvfs: expose FILE_SUPPORTS_SPARSE_FILES capability
    
    Samba now supports:
    - FSCTL_SET_SPARSE
    - FSCTL_SET_ZERO_DATA, via FALLOC_FL_PUNCH_HOLE
    - FSCTL_QUERY_ALLOCATED_RANGES, via SEEK_DATA/SEEK_HOLE
    
    As such, flag support for sparse files, via the
    FILE_SUPPORTS_SPARSE_FILES capability flag if FALLOC_FL_PUNCH_HOLE and
    SEEK_DATA/SEEK_HOLE are present at configure time.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 29531c55928aedc6f860555737cba99689a75d2c
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Feb 19 16:36:05 2015 +0100

    smbd/ioctl: add FSCTL_QUERY_ALLOCATED_RANGES support
    
    This change implements support for FSCTL_QUERY_ALLOCATED_RANGES using
    the SEEK_HOLE/SEEK_DATA functionality of lseek().
    
    Files marked non-sparse are always reported by the ioctl as fully
    allocated, regardless of any potential "strict allocate = no" savings.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 76fff2befe6613416e80f891ccb1521609e19169
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Feb 19 15:53:56 2015 +0100

    build: check for SEEK_HOLE and SEEK_DATA support
    
    SEEK_HOLE and SEEK_DATA will be used in the implementation of
    FSCTL_QUERY_ALLOCATED_RANGES support.
    
    "SEEK_DATA and SEEK_HOLE are nonstandard extensions also present
     in Solaris, FreeBSD, and DragonFly BSD; they are proposed for
     inclusion in the next POSIX revision (Issue 8)."
    
    With Linux they are supported on:
    -  Btrfs (since Linux 3.1)
    -  OCFS (since Linux 3.2)
    -  XFS (since Linux 3.5)
    -  ext4 (since Linux 3.8)
    -  tmpfs (since Linux 3.8)
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b5a635fb0ab0967e375281dd003cd7eb123f73fd
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu Feb 12 10:58:20 2015 +0100

    idl/ioctl: change QAR response array to a DATA_BLOB
    
    [MS-FSCC] specifies:
      The number of FILE_ALLOCATED_RANGE_BUFFER elements returned is
      computed by dividing the size of the returned output buffer (from
      either SMB or SMB2, the lower-layer protocol that carries the FSCTL)
      by the size of the FILE_ALLOCATED_RANGE_BUFFER element.
    
    Ideally, this requirement could be defined in idl with the following:
      [flag(NDR_REMAINING)] file_alloced_range_buf array[];
    
    However, this is not currently supported by PIDL, so just use an opaque
    data blob for now.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 1359e859328567090bf80911083605e17fbd4519
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed Feb 11 00:24:16 2015 +0100

    smbd/ioctl: add FSCTL_SET_ZERO_DATA support
    
    FSCTL_SET_ZERO_DATA can be used in two ways.
    - When requested against a file marked as sparse, it provides a
      mechanism for requesting that the server deallocate the underlying
      disk space for the corresponding zeroed range.
    - When requested against a non-sparse file, it indicates that the server
      should allocate and zero the corresponding range.
    
    Both use cases can be handled in Samba using fallocate(). The Linux
    specific FALLOC_FL_PUNCH_HOLE flag can be used to deallocate the
    underlying disk space. After doing so, a normal fallocate() call can
    be used to ensure that the zeroed range is allocated on non-sparse
    files.
    
    FSCTL_SET_ZERO_DATA requests must not result in a change to the file
    size. The FSCTL_SET_ZERO_DATA handler always calls fallocate() with the
    KEEP_SIZE flag set, ensuring that Samba meets this requirement.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 47f15b14ae4f3a9d83ed6f7c9ad31e74978e9606
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Feb 10 14:32:07 2015 +0100

    system: add hole punch support to sys_fallocate()
    
    If Samba is configured with FALLOC_FL_PUNCH_HOLE support, then allow
    sys_fallocate() to propogate the flag to syscall invocation.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 762f9cbe60fe3a5ee6f528276c095ad736c776ee
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 9 19:39:06 2015 +0100

    build: check for fallocate hole-punch support
    
    Add a configure time check for the FALLOC_FL_PUNCH_HOLE Linux specific
    fallocate() flag. It's been around since 2.6.38.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 12c0b6bf4055b0466d0a2962d5ac34ac60357de3
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 9 18:21:59 2015 +0100

    s3/vfs: change fallocate mode flags from enum->uint32_t
    
    The Linux fallocate syscall offers a mode parameter which can take the
    following flags:
    FALLOC_FL_KEEP_SIZE
    FALLOC_FL_PUNCH_HOLE (since 2.6.38)
    FALLOC_FL_COLLAPSE_RANGE (since 3.15)
    FALLOC_FL_ZERO_RANGE (since 3.14)
    
    The flags are not exclusive, e.g. FALLOC_FL_PUNCH_HOLE must be specified
    alongside FALLOC_FL_KEEP_SIZE.
    
    Samba currently takes a vfs_fallocate_mode enum parameter for the VFS
    fallocate hook, taking either an EXTEND_SIZE or KEEP_SIZE value. This
    commit changes the fallocate hook such that it accepts a uint32_t flags
    parameter, in preparation for PUNCH_HOLE and ZERO_RANGE support.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 3787119eb8d85d122badb22b3bcc15ed5c32765d
Author: David Disseldorp <ddiss at samba.org>
Date:   Mon Feb 9 15:51:28 2015 +0100

    lib/system: remove useless HAVE_LINUX_FALLOCATE64 logic
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

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

Summary of changes:
 examples/VFS/skel_opaque.c          |   2 +-
 examples/VFS/skel_transparent.c     |   2 +-
 librpc/idl/ioctl.idl                |   6 +-
 source3/include/proto.h             |   2 +-
 source3/include/vfs.h               |  17 +-
 source3/lib/system.c                |  36 +-
 source3/modules/vfs_ceph.c          |   3 +-
 source3/modules/vfs_default.c       |  13 +-
 source3/modules/vfs_fruit.c         |   2 +-
 source3/modules/vfs_full_audit.c    |   2 +-
 source3/modules/vfs_glusterfs.c     |   3 +-
 source3/modules/vfs_gpfs.c          |   7 +-
 source3/modules/vfs_streams_xattr.c |   2 +-
 source3/modules/vfs_time_audit.c    |   2 +-
 source3/smbd/dosmode.c              |   9 +-
 source3/smbd/smb2_ioctl_filesys.c   | 328 ++++++++++++-
 source3/smbd/statvfs.c              |   9 +
 source3/smbd/vfs.c                  |  14 +-
 source3/wscript                     |  13 +
 source4/torture/smb2/ioctl.c        | 931 +++++++++++++++++++++++++++++++++---
 20 files changed, 1288 insertions(+), 115 deletions(-)


Changeset truncated at 500 lines:

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 2a53c8a..b6b1aef 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -393,7 +393,7 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static int skel_fallocate(vfs_handle_struct *handle, files_struct *fsp,
-			  enum vfs_fallocate_mode mode, off_t offset, off_t len)
+			  uint32_t mode, off_t offset, off_t len)
 {
 	errno = ENOSYS;
 	return -1;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index eb561db..f7ed537 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -490,7 +490,7 @@ static int skel_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static int skel_fallocate(vfs_handle_struct *handle, files_struct *fsp,
-			  enum vfs_fallocate_mode mode, off_t offset, off_t len)
+			  uint32_t mode, off_t offset, off_t len)
 {
 	return SMB_VFS_NEXT_FALLOCATE(handle, fsp, mode, offset, len);
 }
diff --git a/librpc/idl/ioctl.idl b/librpc/idl/ioctl.idl
index 7760644..d037956 100644
--- a/librpc/idl/ioctl.idl
+++ b/librpc/idl/ioctl.idl
@@ -164,9 +164,13 @@ interface sparse
 	 * computed by dividing the size of the returned output buffer (from
 	 * either SMB or SMB2, the lower-layer protocol that carries the FSCTL)
 	 * by the size of the FILE_ALLOCATED_RANGE_BUFFER element.
+	 *
+	 * This logic can't (currently) be represented in pidl, so just use a
+	 * blob. Perhaps in future we'll support:
+	 *	[flag(NDR_REMAINING)] file_alloced_range_buf array[];
 	 */
 	typedef [public] struct {
-		file_alloced_range_buf *array;
+		[flag(NDR_REMAINING)] DATA_BLOB far_buf_array;
 	} fsctl_query_alloced_ranges_rsp;
 
 	/* 2.3.65 FSCTL_SET_ZERO_DATA Request */
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 64bce03..c66283b 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -255,7 +255,7 @@ int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf,
 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf,
 	      bool fake_dir_create_times);
 int sys_posix_fallocate(int fd, off_t offset, off_t len);
-int sys_fallocate(int fd, enum vfs_fallocate_mode mode, off_t offset, off_t len);
+int sys_fallocate(int fd, uint32_t mode, off_t offset, off_t len);
 void kernel_flock(int fd, uint32 share_mode, uint32 access_mask);
 DIR *sys_fdopendir(int fd);
 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev);
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 13143c2..b2880b7 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -163,6 +163,7 @@
 /* Version 32 - Add in and out create context blobs to create_file */
 /* Version 32 - Remove unnecessary SMB_VFS_DISK_FREE() small_query parameter */
 /* Bump to version 33 - Samba 4.3 will ship with that. */
+/* Version 33 - change fallocate mode flags param from enum->uint32_t */
 
 #define SMB_VFS_INTERFACE_VERSION 33
 
@@ -487,9 +488,9 @@ enum vfs_translate_direction {
 	vfs_translate_to_windows
 };
 
-enum vfs_fallocate_mode {
-	VFS_FALLOCATE_EXTEND_SIZE = 0,
-	VFS_FALLOCATE_KEEP_SIZE = 1
+enum vfs_fallocate_flags {
+	VFS_FALLOCATE_FL_KEEP_SIZE		= 0x0001,
+	VFS_FALLOCATE_FL_PUNCH_HOLE		= 0x0002,
 };
 
 /*
@@ -609,7 +610,7 @@ struct vfs_fn_pointers {
 	int (*ftruncate_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, off_t offset);
 	int (*fallocate_fn)(struct vfs_handle_struct *handle,
 			    struct files_struct *fsp,
-			    enum vfs_fallocate_mode mode,
+			    uint32_t mode,
 			    off_t offset,
 			    off_t len);
 	bool (*lock_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, int op, off_t offset, off_t count, int type);
@@ -1050,10 +1051,10 @@ int smb_vfs_call_ntimes(struct vfs_handle_struct *handle,
 int smb_vfs_call_ftruncate(struct vfs_handle_struct *handle,
 			   struct files_struct *fsp, off_t offset);
 int smb_vfs_call_fallocate(struct vfs_handle_struct *handle,
-			struct files_struct *fsp,
-			enum vfs_fallocate_mode mode,
-			off_t offset,
-			off_t len);
+			   struct files_struct *fsp,
+			   uint32_t mode,
+			   off_t offset,
+			   off_t len);
 bool smb_vfs_call_lock(struct vfs_handle_struct *handle,
 		       struct files_struct *fsp, int op, off_t offset,
 		       off_t count, int type);
diff --git a/source3/lib/system.c b/source3/lib/system.c
index 7531d77..aba9574 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -478,29 +478,35 @@ int sys_posix_fallocate(int fd, off_t offset, off_t len)
 #include <linux/falloc.h>
 #endif
 
-int sys_fallocate(int fd, enum vfs_fallocate_mode mode, off_t offset, off_t len)
+int sys_fallocate(int fd, uint32_t mode, off_t offset, 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:
+#if defined(HAVE_LINUX_FALLOCATE)
+	int lmode = 0;
+
+	if (mode & VFS_FALLOCATE_FL_KEEP_SIZE) {
+		lmode |= FALLOC_FL_KEEP_SIZE;
+		mode &= ~VFS_FALLOCATE_FL_KEEP_SIZE;
+	}
+
+#if defined(HAVE_FALLOC_FL_PUNCH_HOLE)
+	if (mode & VFS_FALLOCATE_FL_PUNCH_HOLE) {
+		lmode |= FALLOC_FL_PUNCH_HOLE;
+		mode &= ~VFS_FALLOCATE_FL_PUNCH_HOLE;
+	}
+#endif	/* HAVE_FALLOC_FL_PUNCH_HOLE */
+
+	if (mode != 0) {
+		DEBUG(2, ("unmapped fallocate flags: %lx\n",
+		      (unsigned long)mode));
 		errno = EINVAL;
 		return -1;
 	}
-#if defined(HAVE_LINUX_FALLOCATE)
 	return fallocate(fd, lmode, offset, len);
-#endif
-#else
+#else	/* HAVE_LINUX_FALLOCATE */
 	/* TODO - plumb in fallocate from other filesysetms like VXFS etc. JRA. */
 	errno = ENOSYS;
 	return -1;
-#endif
+#endif	/* HAVE_LINUX_FALLOCATE */
 }
 
 #if HAVE_KERNEL_SHARE_MODES
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 0967428..d53a2de 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -796,8 +796,7 @@ static int strict_allocate_ftruncate(struct vfs_handle_struct *handle, files_str
 	   emulation is being done by the libc (like on AIX with JFS1). In that
 	   case we do our own emulation. fallocate implementations can
 	   return ENOTSUP or EINVAL in cases like that. */
-	ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
-				pst->st_ex_size, space_to_write);
+	ret = SMB_VFS_FALLOCATE(fsp, 0, pst->st_ex_size, space_to_write);
 	if (ret == -1 && errno == ENOSPC) {
 		return -1;
 	}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 31648f6..fdb90e4 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1861,8 +1861,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. fallocate implementations can
 	   return ENOTSUP or EINVAL in cases like that. */
-	ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_EXTEND_SIZE,
-				pst->st_ex_size, space_to_write);
+	ret = SMB_VFS_FALLOCATE(fsp, 0, pst->st_ex_size, space_to_write);
 	if (ret == -1 && errno == ENOSPC) {
 		return -1;
 	}
@@ -1962,14 +1961,14 @@ static int vfswrap_ftruncate(vfs_handle_struct *handle, files_struct *fsp, off_t
 
 static int vfswrap_fallocate(vfs_handle_struct *handle,
 			files_struct *fsp,
-			enum vfs_fallocate_mode mode,
+			uint32_t mode,
 			off_t offset,
 			off_t len)
 {
 	int result;
 
 	START_PROFILE(syscall_fallocate);
-	if (mode == VFS_FALLOCATE_EXTEND_SIZE) {
+	if (mode == 0) {
 		result = sys_posix_fallocate(fsp->fh->fd, offset, len);
 		/*
 		 * posix_fallocate returns 0 on success, errno on error
@@ -1980,11 +1979,9 @@ static int vfswrap_fallocate(vfs_handle_struct *handle,
 			errno = result;
 			result = -1;
 		}
-	} else if (mode == VFS_FALLOCATE_KEEP_SIZE) {
-		result = sys_fallocate(fsp->fh->fd, mode, offset, len);
 	} else {
-		errno = EINVAL;
-		result = -1;
+		/* sys_fallocate handles filtering of unsupported mode flags */
+		result = sys_fallocate(fsp->fh->fd, mode, offset, len);
 	}
 	END_PROFILE(syscall_fallocate);
 	return result;
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 0445e04..fbee321 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -3039,7 +3039,7 @@ exit:
 
 static int fruit_fallocate(struct vfs_handle_struct *handle,
 			   struct files_struct *fsp,
-			   enum vfs_fallocate_mode mode,
+			   uint32_t mode,
 			   off_t offset,
 			   off_t len)
 {
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index b7a4eee..87a2f9c 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1452,7 +1452,7 @@ static int smb_full_audit_ftruncate(vfs_handle_struct *handle, files_struct *fsp
 }
 
 static int smb_full_audit_fallocate(vfs_handle_struct *handle, files_struct *fsp,
-			   enum vfs_fallocate_mode mode,
+			   uint32_t mode,
 			   off_t offset,
 			   off_t len)
 {
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index 09c789c..2c7266e 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -927,9 +927,10 @@ static int vfs_gluster_ftruncate(struct vfs_handle_struct *handle,
 
 static int vfs_gluster_fallocate(struct vfs_handle_struct *handle,
 				 struct files_struct *fsp,
-				 enum vfs_fallocate_mode mode,
+				 uint32_t mode,
 				 off_t offset, off_t len)
 {
+	/* TODO: add support using glfs_fallocate() and glfs_zerofill() */
 	errno = ENOTSUP;
 	return -1;
 }
diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c
index 21707c5..999e83b 100644
--- a/source3/modules/vfs_gpfs.c
+++ b/source3/modules/vfs_gpfs.c
@@ -1843,7 +1843,7 @@ static int vfs_gpfs_ntimes(struct vfs_handle_struct *handle,
 }
 
 static int vfs_gpfs_fallocate(struct vfs_handle_struct *handle,
-		       struct files_struct *fsp, enum vfs_fallocate_mode mode,
+		       struct files_struct *fsp, uint32_t mode,
 		       off_t offset, off_t len)
 {
 	int ret;
@@ -1859,8 +1859,9 @@ static int vfs_gpfs_fallocate(struct vfs_handle_struct *handle,
 		return -1;
 	}
 
-	if (mode == VFS_FALLOCATE_KEEP_SIZE) {
-		DEBUG(10, ("Unsupported VFS_FALLOCATE_KEEP_SIZE\n"));
+	if (mode != 0) {
+		DEBUG(10, ("unmapped fallocate flags: %lx\n",
+		      (unsigned long)mode));
 		errno = ENOTSUP;
 		return -1;
 	}
diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c
index b3c1df1..52a9059 100644
--- a/source3/modules/vfs_streams_xattr.c
+++ b/source3/modules/vfs_streams_xattr.c
@@ -1093,7 +1093,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle,
 
 static int streams_xattr_fallocate(struct vfs_handle_struct *handle,
 					struct files_struct *fsp,
-					enum vfs_fallocate_mode mode,
+					uint32_t mode,
 					off_t offset,
 					off_t len)
 {
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 04552ec..45e30ac 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1209,7 +1209,7 @@ static int smb_time_audit_ftruncate(vfs_handle_struct *handle,
 
 static int smb_time_audit_fallocate(vfs_handle_struct *handle,
 				    files_struct *fsp,
-				    enum vfs_fallocate_mode mode,
+				    uint32_t mode,
 				    off_t offset,
 				    off_t len)
 {
diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c
index 6fd5d69..8c0781b 100644
--- a/source3/smbd/dosmode.c
+++ b/source3/smbd/dosmode.c
@@ -876,8 +876,13 @@ NTSTATUS file_set_sparse(connection_struct *conn,
 		return NT_STATUS_MEDIA_WRITE_PROTECTED;
 	}
 
-	if (!(fsp->access_mask & FILE_WRITE_DATA) &&
-			!(fsp->access_mask & FILE_WRITE_ATTRIBUTES)) {
+	/*
+	 * Windows Server 2008 & 2012 permit FSCTL_SET_SPARSE if any of the
+	 * following access flags are granted.
+	 */
+	if ((fsp->access_mask & (FILE_WRITE_DATA
+				| FILE_WRITE_ATTRIBUTES
+				| SEC_FILE_APPEND_DATA)) == 0) {
 		DEBUG(9,("file_set_sparse: fname[%s] set[%u] "
 			"access_mask[0x%08X] - access denied\n",
 			smb_fname_str_dbg(fsp->fsp_name),
diff --git a/source3/smbd/smb2_ioctl_filesys.c b/source3/smbd/smb2_ioctl_filesys.c
index 92bf63a..187deaf 100644
--- a/source3/smbd/smb2_ioctl_filesys.c
+++ b/source3/smbd/smb2_ioctl_filesys.c
@@ -3,7 +3,7 @@
    Core SMB2 server
 
    Copyright (C) Stefan Metzmacher 2009
-   Copyright (C) David Disseldorp 2013
+   Copyright (C) David Disseldorp 2013-2015
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -123,6 +123,314 @@ static NTSTATUS fsctl_set_cmprn(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS fsctl_zero_data(TALLOC_CTX *mem_ctx,
+				struct tevent_context *ev,
+				struct files_struct *fsp,
+				DATA_BLOB *in_input)
+{
+	struct file_zero_data_info zdata_info;
+	enum ndr_err_code ndr_ret;
+	struct lock_struct lck;
+	int mode;
+	uint64_t len;
+	int ret;
+	NTSTATUS status;
+
+	if (fsp == NULL) {
+		return NT_STATUS_FILE_CLOSED;
+	}
+
+	/* WRITE_DATA permission is required */
+	status = check_access(fsp->conn, fsp, NULL, FILE_WRITE_DATA);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* allow regardless of whether FS supports sparse or not */
+
+	ndr_ret = ndr_pull_struct_blob(in_input, mem_ctx, &zdata_info,
+			(ndr_pull_flags_fn_t)ndr_pull_file_zero_data_info);
+	if (ndr_ret != NDR_ERR_SUCCESS) {
+		DEBUG(0, ("failed to unmarshall zero data request\n"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	if (zdata_info.beyond_final_zero < zdata_info.file_off) {
+		DEBUG(0, ("invalid zero data params: off %lu, bfz, %lu\n",
+			  (unsigned long)zdata_info.file_off,
+			  (unsigned long)zdata_info.beyond_final_zero));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* convert strange "beyond final zero" param into length */
+	len = zdata_info.beyond_final_zero - zdata_info.file_off;
+
+	if (len == 0) {
+		DEBUG(2, ("zero data called with zero length range\n"));
+		return NT_STATUS_OK;
+	}
+
+	init_strict_lock_struct(fsp,
+				fsp->op->global->open_persistent_id,
+				zdata_info.file_off,
+				len,
+				WRITE_LOCK,
+				&lck);
+
+	if (!SMB_VFS_STRICT_LOCK(fsp->conn, fsp, &lck)) {
+		DEBUG(2, ("failed to lock range for zero-data\n"));
+		return NT_STATUS_FILE_LOCK_CONFLICT;
+	}
+
+	/*
+	 * MS-FSCC <58> Section 2.3.65
+	 * This FSCTL sets the range of bytes to zero (0) without extending the
+	 * file size.
+	 *
+	 * The VFS_FALLOCATE_FL_KEEP_SIZE flag is used to satisfy this
+	 * constraint.
+	 */
+
+	mode = VFS_FALLOCATE_FL_PUNCH_HOLE | VFS_FALLOCATE_FL_KEEP_SIZE;
+	ret = SMB_VFS_FALLOCATE(fsp, mode, zdata_info.file_off, len);
+	if (ret == -1)  {
+		status = map_nt_error_from_unix_common(errno);
+		DEBUG(2, ("zero-data fallocate(0x%x) failed: %s\n", mode,
+		      strerror(errno)));
+		SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &lck);
+		return status;
+	}
+
+	if (!fsp->is_sparse && lp_strict_allocate(SNUM(fsp->conn))) {
+		/*
+		 * File marked non-sparse and "strict allocate" is enabled -
+		 * allocate the range that we just punched out.
+		 * In future FALLOC_FL_ZERO_RANGE could be used exclusively for
+		 * this, but it's currently only supported on XFS and ext4.
+		 *
+		 * The newly allocated range still won't be found by SEEK_DATA
+		 * for QAR, but stat.st_blocks will reflect it.
+		 */
+		ret = SMB_VFS_FALLOCATE(fsp, VFS_FALLOCATE_FL_KEEP_SIZE,
+					zdata_info.file_off, len);
+		if (ret == -1)  {
+			status = map_nt_error_from_unix_common(errno);
+			DEBUG(0, ("fallocate failed: %s\n", strerror(errno)));
+			SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &lck);
+			return status;
+		}
+	}
+
+	SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &lck);
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS fsctl_qar_buf_push(TALLOC_CTX *mem_ctx,
+				   struct file_alloced_range_buf *qar_buf,
+				   DATA_BLOB *qar_array_blob)
+{
+	DATA_BLOB new_slot;
+	enum ndr_err_code ndr_ret;
+	bool ok;
+
+	ndr_ret = ndr_push_struct_blob(&new_slot, mem_ctx, qar_buf,
+			(ndr_push_flags_fn_t)ndr_push_file_alloced_range_buf);
+	if (ndr_ret != NDR_ERR_SUCCESS) {
+		DEBUG(0, ("failed to marshall QAR buf\n"));
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* TODO should be able to avoid copy by pushing into prealloced buf */
+	ok = data_blob_append(mem_ctx, qar_array_blob, new_slot.data,
+			      new_slot.length);
+	data_blob_free(&new_slot);
+	if (!ok) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS fsctl_qar_seek_fill(TALLOC_CTX *mem_ctx,
+				    struct files_struct *fsp,
+				    off_t curr_off,
+				    off_t max_off,
+				    DATA_BLOB *qar_array_blob)
+{
+	NTSTATUS status = NT_STATUS_NOT_SUPPORTED;
+
+#ifdef HAVE_LSEEK_HOLE_DATA
+	while (curr_off <= max_off) {
+		off_t data_off;
+		off_t hole_off;
+		struct file_alloced_range_buf qar_buf;
+
+		/* seek next data */
+		data_off = SMB_VFS_LSEEK(fsp, curr_off, SEEK_DATA);
+		if ((data_off == -1) && (errno == ENXIO)) {
+			/* no data from curr_off to EOF */
+			break;
+		} else if (data_off == -1) {
+			status = map_nt_error_from_unix_common(errno);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list