[SCM] Samba Shared Repository - branch master updated

Ralph Böhme slow at samba.org
Wed May 10 10:28:02 UTC 2017


The branch, master has been updated
       via  de01e11 smbd/smb2_ioctl: instruct VFS to ignore locks for dup extents
       via  c4fd960 vfs: add VFS_COPY_CHUNK_FL_IGNORE_LOCKS for dup extents
       via  b97d8c8 smbd/smb2_ioctl: validate dup_extent request lengths
       via  fb31e35 smbd/smb2_ioctl: check sparseness for dup extents
       via  e953184 vfs_btrfs: report FILE_SUPPORTS_BLOCK_REFCOUNTING capability
       via  a222108 smbd/smb2_ioctl: check for for overlap of dup extent ranges
       via  373d301 smbd/smb2_ioctl: add support for FSCTL_DUPLICATE_EXTENTS_TO_FILE
       via  fc2b366 vfs: add parameter to copy chunk VFS function to handle dup_extents
       via  3361b5f torture/ioctl: expect dup_extents(dest=compressed) to pass
       via  3b4d626 torture/ioctl: fix dup_extents destination truncate
      from  da95471 packaging: Remove Mandrake

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


- Log -----------------------------------------------------------------
commit de01e117d65219e5765e8e83730aa00c4bac5b6b
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu May 4 15:09:36 2017 +0200

    smbd/smb2_ioctl: instruct VFS to ignore locks for dup extents
    
    As described in the previous commit - Windows Server 2016 (ReFS) ignores
    locks for FSCTL_DUPLICATE_EXTENTS_TO_FILE. Do the same for Samba.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>
    
    Autobuild-User(master): Ralph Böhme <slow at samba.org>
    Autobuild-Date(master): Wed May 10 12:27:00 CEST 2017 on sn-devel-144

commit c4fd96016610171a31ad54a7883b3682680ef8d1
Author: David Disseldorp <ddiss at samba.org>
Date:   Thu May 4 14:55:43 2017 +0200

    vfs: add VFS_COPY_CHUNK_FL_IGNORE_LOCKS for dup extents
    
    As confirmed by the Microsoft Protocol Open Specifications Team: Windows
    Server 2016 (ReFS) ignores locks for FSCTL_DUPLICATE_EXTENTS_TO_FILE...
    
    From: Jeff McCashland
    To: David Disseldorp
    CC: "cifs-protocol at lists.samba.org" <cifs-protocol at lists.samba.org>
    Subject: RE: [116100414754619] FSCTL_DUPLICATE_EXTENTS_TO_FILE appears
    	 to completely bypass file locks
    Date: Mon, 12 Dec 2016 20:44:08 +0000
    
    Hi David,
    
    We have made the following spec changes for the next doc release:
    
    In section 2.1.5.9.4 FSCTL_DUPLICATE_EXTENTS_TO_FILE behavior notes have
    been added to the following paragraphs.
    
    Before:
    § The object store MUST check for byte range lock conflicts on
    Open.Stream using the algorithm described in section 2.1.4.10 with
    ByteOffset set to InputBuffer.TargetFileOffset, Length set to
    InputBuffer.ByteCount, IsExclusive set to TRUE, LockIntent set to FALSE,
    and Open set to Open. If a conflict is detected, the operation MUST be
    failed with STATUS_FILE_LOCK_CONFLICT.
    
    § The object store MUST check for byte range lock conflicts on Source
    using the algorithm described in section 2.1.4.10 with ByteOffset set to
    InputBuffer.SourceFileOffset, Length set to InputBuffer.ByteCount,
    IsExclusive set to FALSE, LockIntent set to FALSE, and Open set to
    InputBuffer.FileHandle. If a conflict is detected, the operation MUST be
    failed with STATUS_FILE_LOCK_CONFLICT.
    
    After:
    § The object store SHOULD<WBN1> check for byte range lock conflicts on
    Open.Stream using the algorithm described in section 2.1.4.10 with
    ByteOffset set to InputBuffer.TargetFileOffset, Length set to
    InputBuffer.ByteCount, IsExclusive set to TRUE, LockIntent set to FALSE,
    and Open set to Open. If a conflict is detected, the operation MUST be
    failed with STATUS_FILE_LOCK_CONFLICT.
    
    § The object store SHOULD<WBN2> check for byte range lock conflicts on
    Source using the algorithm described in section 2.1.4.10 with ByteOffset
    set to InputBuffer.SourceFileOffset, Length set to
    InputBuffer.ByteCount, IsExclusive set to FALSE, LockIntent set to
    FALSE, and Open set to InputBuffer.FileHandle. If a conflict is
    detected, the operation MUST be failed with STATUS_FILE_LOCK_CONFLICT.
    
    WBN1: The ReFS file system in Windows Server 2016 does not check for
    byte range lock conflicts on Open.Stream.
    WBN2: The ReFS file system in Windows Server 2016 does not check for
    byte range lock conflicts on Source.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit b97d8c81a7d4be7ba4e050dea4c963645721132c
Author: David Disseldorp <ddiss at samba.org>
Date:   Sat Oct 1 23:40:13 2016 +0200

    smbd/smb2_ioctl: validate dup_extent request lengths
    
    FSCTL_DUPLICATE_EXTENTS_TO_FILE has some interesting behaviour when
    exceeding the destination file length - the clone is truncated to only
    cover the existing file region. If the existing length is zero, then
    nothing is cloned.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit fb31e359bf8e80ece6641bc1a7e6a1e2a5e67ddb
Author: David Disseldorp <ddiss at samba.org>
Date:   Fri Sep 30 20:53:07 2016 +0200

    smbd/smb2_ioctl: check sparseness for dup extents
    
    FSCTL_DUPLICATE_EXTENTS_TO_FILE should fail if the source is marked
    sparse while the target is not:
    
    From: Jeff McCashland
    To: David Disseldorp
    Subject: RE: FSCTL_DUPLICATE_EXTENTS_TO_FILE questions, 116092214702946
    Date: Tue, 27 Dec 2016 18:06:14 +0000
    
    ...
    We have updated the spec for future release:
    
    Section 2.3.8 FSCTL_DUPLICATE_EXTENTS_TO_FILE Reply
    Changed description of STATUS_NOT_SUPPORTED error code to:
    "--The source and target destination ranges overlap on the same file.
    --Source file is sparse, while -target is a non-sparse file.
    --The source range is beyond the source file's allocation size."
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit e95318466255323ab22e772c12219cc738d15177
Author: Aurelien Aptel <aaptel at suse.com>
Date:   Thu Jul 30 16:33:08 2015 +0200

    vfs_btrfs: report FILE_SUPPORTS_BLOCK_REFCOUNTING capability
    
    Signed-off-by: Aurelien Aptel <aaptel at suse.com>
    Reviewed-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit a222108284dca32f216fc9047715ba5dbc9ecbdf
Author: David Disseldorp <ddiss at samba.org>
Date:   Tue Sep 20 09:48:37 2016 -0700

    smbd/smb2_ioctl: check for for overlap of dup extent ranges
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 373d3015bc7c42d8ab28e72cd76806cce1d9c78f
Author: Aurelien Aptel <aaptel at suse.com>
Date:   Thu Jul 30 16:16:15 2015 +0200

    smbd/smb2_ioctl: add support for FSCTL_DUPLICATE_EXTENTS_TO_FILE
    
    Signed-off-by: Aurelien Aptel <aaptel at suse.com>
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit fc2b3662b813e936458860c3c041ee50e5dd1a88
Author: Aurelien Aptel <aaptel at suse.com>
Date:   Mon Aug 24 18:22:56 2015 +0200

    vfs: add parameter to copy chunk VFS function to handle dup_extents
    
    FSCTL_DUPLICATE_EXTENTS_TO_FILE must be handled as a COW clone. Add a
    copy-chunk flags parameter to the VFS to handle this.
    
    Signed-off-by: Aurelien Aptel <aaptel at suse.com>
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 3361b5fca390c9ab130160dbbdd25a0be97bd818
Author: David Disseldorp <ddiss at samba.org>
Date:   Fri Sep 30 21:35:09 2016 +0200

    torture/ioctl: expect dup_extents(dest=compressed) to pass
    
    The MS-FSCC spec doesn't mention anything about dup-extents against
    compressed files.
    This can't be tested against Windows, as ReFS doesn't support
    compression, but COW clones of compressed files work on Btrfs.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

commit 3b4d6267d1108d44b79b8bf5d92ec01c917a3397
Author: David Disseldorp <ddiss at samba.org>
Date:   Wed May 3 09:26:43 2017 +0200

    torture/ioctl: fix dup_extents destination truncate
    
    The dup_extents_compressed_dest test fails to correctly truncate the
    dup_extents destination. Fix it.
    
    Signed-off-by: David Disseldorp <ddiss at samba.org>
    Reviewed-by: Ralph Böhme <slow at samba.org>

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

Summary of changes:
 examples/VFS/skel_opaque.c           |   3 +-
 examples/VFS/skel_transparent.c      |   5 +-
 source3/include/vfs.h                |  21 ++-
 source3/include/vfs_macros.h         |   8 +-
 source3/modules/vfs_btrfs.c          |  68 ++++----
 source3/modules/vfs_default.c        |  86 ++++++----
 source3/modules/vfs_fruit.c          |   6 +-
 source3/modules/vfs_full_audit.c     |   6 +-
 source3/modules/vfs_time_audit.c     |   5 +-
 source3/smbd/smb2_ioctl_filesys.c    | 300 +++++++++++++++++++++++++++++++++++
 source3/smbd/smb2_ioctl_network_fs.c |   4 +-
 source3/smbd/vfs.c                   |   6 +-
 source4/torture/smb2/ioctl.c         |  13 +-
 13 files changed, 450 insertions(+), 81 deletions(-)


Changeset truncated at 500 lines:

diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index ffd951c..af119f3 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -531,7 +531,8 @@ static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle,
 					       off_t src_off,
 					       struct files_struct *dest_fsp,
 					       off_t dest_off,
-					       off_t num)
+					       off_t num,
+					       uint32_t flags)
 {
 	struct tevent_req *req;
 	struct skel_cc_state *cc_state;
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index afadbc1..e974529 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -619,7 +619,8 @@ static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle,
 					       off_t src_off,
 					       struct files_struct *dest_fsp,
 					       off_t dest_off,
-					       off_t num)
+					       off_t num,
+					       uint32_t flags)
 {
 	struct tevent_req *req;
 	struct tevent_req *subreq;
@@ -633,7 +634,7 @@ static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle,
 	cc_state->handle = handle;
 	subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, cc_state, ev,
 					      src_fsp, src_off,
-					      dest_fsp, dest_off, num);
+					      dest_fsp, dest_off, num, flags);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index f6df93a..7908980 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -196,6 +196,7 @@
 /* Bump to version 36 - Samba 4.6 will ship with that */
 /* Version 36 - Remove is_offline and set_offline */
 /* Version 37 - Module init functions now take a TALLOC_CTX * parameter. */
+/* Version 37 - Add vfs_copy_chunk_flags for DUP_EXTENTS_TO_FILE */
 
 #define SMB_VFS_INTERFACE_VERSION 37
 
@@ -548,6 +549,20 @@ enum vfs_fallocate_flags {
 	VFS_FALLOCATE_FL_PUNCH_HOLE		= 0x0002,
 };
 
+/*
+ * @VFS_COPY_CHUNK_FL_MUST_CLONE: indicates that copy_chunk_send_fn() copy must
+ *				  be handled as a COW clone, AKA reflink.
+ * @VFS_COPY_CHUNK_FL_MASK_ALL: all valid copychunk flags.
+ */
+enum vfs_copy_chunk_flags {
+	VFS_COPY_CHUNK_FL_MUST_CLONE		= 0x0001,
+	VFS_COPY_CHUNK_FL_IGNORE_LOCKS		= 0x0002,
+
+	VFS_COPY_CHUNK_FL_MASK_ALL		=
+					(VFS_COPY_CHUNK_FL_MUST_CLONE
+					 | VFS_COPY_CHUNK_FL_IGNORE_LOCKS),
+};
+
 struct vfs_aio_state {
 	int error;
 	uint64_t duration;
@@ -709,7 +724,8 @@ struct vfs_fn_pointers {
 						 off_t src_off,
 						 struct files_struct *dest_fsp,
 						 off_t dest_off,
-						 off_t num);
+						 off_t to_copy,
+						 uint32_t flags);
 	NTSTATUS (*copy_chunk_recv_fn)(struct vfs_handle_struct *handle,
 				       struct tevent_req *req,
 				       off_t *copied);
@@ -1241,7 +1257,8 @@ struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle
 						off_t src_off,
 						struct files_struct *dest_fsp,
 						off_t dest_off,
-						off_t num);
+						off_t num,
+						uint32_t flags);
 NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
 				      struct tevent_req *req,
 				      off_t *copied);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 40c93f8..0cbcf89 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -415,10 +415,10 @@
 #define SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, attributes) \
 	smb_vfs_call_fset_dos_attributes((handle)->next, (fsp), (attributes))
 
-#define SMB_VFS_COPY_CHUNK_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \
-	smb_vfs_call_copy_chunk_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num))
-#define SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num) \
-	smb_vfs_call_copy_chunk_send((handle)->next, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num))
+#define SMB_VFS_COPY_CHUNK_SEND(conn, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num, flags) \
+	smb_vfs_call_copy_chunk_send((conn)->vfs_handles, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num), (flags))
+#define SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp, src_off, dest_fsp, dest_off, num, flags) \
+	smb_vfs_call_copy_chunk_send((handle)->next, (mem_ctx), (ev), (src_fsp), (src_off), (dest_fsp), (dest_off), (num), (flags))
 
 #define SMB_VFS_COPY_CHUNK_RECV(conn, req, copied) \
 	smb_vfs_call_copy_chunk_recv((conn)->vfs_handles, (req), (copied))
diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index ab4fd99..e306ece 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -39,7 +39,8 @@ static uint32_t btrfs_fs_capabilities(struct vfs_handle_struct *handle,
 
 	/* inherit default capabilities, expose compression support */
 	fs_capabilities = SMB_VFS_NEXT_FS_CAPABILITIES(handle, &ts_res);
-	fs_capabilities |= FILE_FILE_COMPRESSION;
+	fs_capabilities |= (FILE_FILE_COMPRESSION
+			    | FILE_SUPPORTS_BLOCK_REFCOUNTING);
 	*_ts_res = ts_res;
 
 	return fs_capabilities;
@@ -92,7 +93,8 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 						off_t src_off,
 						struct files_struct *dest_fsp,
 						off_t dest_off,
-						off_t num)
+						off_t num,
+						uint32_t flags)
 {
 	struct tevent_req *req;
 	struct btrfs_cc_state *cc_state;
@@ -106,6 +108,12 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 	if (req == NULL) {
 		return NULL;
 	}
+
+	if (flags & ~VFS_COPY_CHUNK_FL_MASK_ALL) {
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+		return tevent_req_post(req, ev);
+	}
+
 	cc_state->handle = handle;
 
 	if (num == 0) {
@@ -119,7 +127,8 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 								src_fsp,
 								src_off,
 								dest_fsp,
-								dest_off, num);
+								dest_off,
+								num, flags);
 		if (tevent_req_nomem(cc_state->subreq, req)) {
 			return tevent_req_post(req, ev);
 		}
@@ -145,27 +154,29 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 		return tevent_req_post(req, ev);
 	}
 
-	init_strict_lock_struct(src_fsp,
-				src_fsp->op->global->open_persistent_id,
-				src_off,
-				num,
-				READ_LOCK,
-				&src_lck);
-	init_strict_lock_struct(dest_fsp,
-				dest_fsp->op->global->open_persistent_id,
-				dest_off,
-				num,
-				WRITE_LOCK,
-				&dest_lck);
-
-	if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &src_lck)) {
-		tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-		return tevent_req_post(req, ev);
-	}
-	if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &dest_lck)) {
-		SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
-		tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-		return tevent_req_post(req, ev);
+	if (!(flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+		init_strict_lock_struct(src_fsp,
+					src_fsp->op->global->open_persistent_id,
+					src_off,
+					num,
+					READ_LOCK,
+					&src_lck);
+		init_strict_lock_struct(dest_fsp,
+				       dest_fsp->op->global->open_persistent_id,
+					dest_off,
+					num,
+					WRITE_LOCK,
+					&dest_lck);
+
+		if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &src_lck)) {
+			tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+			return tevent_req_post(req, ev);
+		}
+		if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &dest_lck)) {
+			SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
+			tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+			return tevent_req_post(req, ev);
+		}
 	}
 
 	ZERO_STRUCT(cr_args);
@@ -175,8 +186,10 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 	cr_args.src_length = (uint64_t)num;
 
 	ret = ioctl(dest_fsp->fh->fd, BTRFS_IOC_CLONE_RANGE, &cr_args);
-	SMB_VFS_STRICT_UNLOCK(dest_fsp->conn, dest_fsp, &dest_lck);
-	SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
+	if (!(flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+		SMB_VFS_STRICT_UNLOCK(dest_fsp->conn, dest_fsp, &dest_lck);
+		SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &src_lck);
+	}
 	if (ret < 0) {
 		/*
 		 * BTRFS_IOC_CLONE_RANGE only supports 'sectorsize' aligned
@@ -196,7 +209,8 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 								src_fsp,
 								src_off,
 								dest_fsp,
-								dest_off, num);
+								dest_off,
+								num, flags);
 		if (tevent_req_nomem(cc_state->subreq, req)) {
 			return tevent_req_post(req, ev);
 		}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index d660120..fa89f7f 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1605,6 +1605,7 @@ struct vfs_cc_state {
 	off_t to_copy;
 	off_t remaining;
 	size_t next_io_size;
+	uint32_t flags;
 };
 
 static NTSTATUS copy_chunk_loop(struct tevent_req *req);
@@ -1616,7 +1617,8 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
 						  off_t src_off,
 						  struct files_struct *dest_fsp,
 						  off_t dest_off,
-						  off_t to_copy)
+						  off_t to_copy,
+						  uint32_t flags)
 {
 	struct tevent_req *req;
 	struct vfs_cc_state *state = NULL;
@@ -1630,6 +1632,17 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
 		return NULL;
 	}
 
+	if (flags & ~VFS_COPY_CHUNK_FL_MASK_ALL) {
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+		return tevent_req_post(req, ev);
+	}
+
+	if (flags & VFS_COPY_CHUNK_FL_MUST_CLONE) {
+		DEBUG(10, ("COW clones not supported by vfs_default\n"));
+		tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+		return tevent_req_post(req, ev);
+	}
+
 	*state = (struct vfs_cc_state) {
 		.ev = ev,
 		.src_fsp = src_fsp,
@@ -1638,6 +1651,7 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
 		.dst_off = dest_off,
 		.to_copy = to_copy,
 		.remaining = to_copy,
+		.flags = flags,
 	};
 	state->buf = talloc_array(state, uint8_t, num);
 	if (tevent_req_nomem(state->buf, req)) {
@@ -1692,18 +1706,20 @@ static NTSTATUS copy_chunk_loop(struct tevent_req *req)
 
 	state->next_io_size = MIN(state->remaining, talloc_array_length(state->buf));
 
-	init_strict_lock_struct(state->src_fsp,
+	if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+		init_strict_lock_struct(state->src_fsp,
 				state->src_fsp->op->global->open_persistent_id,
-				state->src_off,
-				state->next_io_size,
-				READ_LOCK,
-				&state->read_lck);
-
-	ok = SMB_VFS_STRICT_LOCK(state->src_fsp->conn,
-				 state->src_fsp,
-				 &state->read_lck);
-	if (!ok) {
-		return NT_STATUS_FILE_LOCK_CONFLICT;
+					state->src_off,
+					state->next_io_size,
+					READ_LOCK,
+					&state->read_lck);
+
+		ok = SMB_VFS_STRICT_LOCK(state->src_fsp->conn,
+					 state->src_fsp,
+					 &state->read_lck);
+		if (!ok) {
+			return NT_STATUS_FILE_LOCK_CONFLICT;
+		}
 	}
 
 	subreq = SMB_VFS_PREAD_SEND(state,
@@ -1731,10 +1747,12 @@ static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq)
 	ssize_t nread;
 	bool ok;
 
-	SMB_VFS_STRICT_UNLOCK(state->src_fsp->conn,
-			      state->src_fsp,
-			      &state->read_lck);
-	ZERO_STRUCT(state->read_lck);
+	if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+		SMB_VFS_STRICT_UNLOCK(state->src_fsp->conn,
+				      state->src_fsp,
+				      &state->read_lck);
+		ZERO_STRUCT(state->read_lck);
+	}
 
 	nread = SMB_VFS_PREAD_RECV(subreq, &aio_state);
 	TALLOC_FREE(subreq);
@@ -1752,19 +1770,21 @@ static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq)
 
 	state->src_off += nread;
 
-	init_strict_lock_struct(state->dst_fsp,
+	if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+		init_strict_lock_struct(state->dst_fsp,
 				state->dst_fsp->op->global->open_persistent_id,
-				state->dst_off,
-				state->next_io_size,
-				WRITE_LOCK,
-				&state->write_lck);
-
-	ok = SMB_VFS_STRICT_LOCK(state->dst_fsp->conn,
-				 state->dst_fsp,
-				 &state->write_lck);
-	if (!ok) {
-		tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-		return;
+					state->dst_off,
+					state->next_io_size,
+					WRITE_LOCK,
+					&state->write_lck);
+
+		ok = SMB_VFS_STRICT_LOCK(state->dst_fsp->conn,
+					 state->dst_fsp,
+					 &state->write_lck);
+		if (!ok) {
+			tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+			return;
+		}
 	}
 
 	subreq = SMB_VFS_PWRITE_SEND(state,
@@ -1789,10 +1809,12 @@ static void vfswrap_copy_chunk_write_done(struct tevent_req *subreq)
 	ssize_t nwritten;
 	NTSTATUS status;
 
-	SMB_VFS_STRICT_UNLOCK(state->dst_fsp->conn,
-			      state->dst_fsp,
-			      &state->write_lck);
-	ZERO_STRUCT(state->write_lck);
+	if (!(state->flags & VFS_COPY_CHUNK_FL_IGNORE_LOCKS)) {
+		SMB_VFS_STRICT_UNLOCK(state->dst_fsp->conn,
+				      state->dst_fsp,
+				      &state->write_lck);
+		ZERO_STRUCT(state->write_lck);
+	}
 
 	nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state);
 	TALLOC_FREE(subreq);
diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c
index 273540e..ee8cdb7 100644
--- a/source3/modules/vfs_fruit.c
+++ b/source3/modules/vfs_fruit.c
@@ -5233,7 +5233,8 @@ static struct tevent_req *fruit_copy_chunk_send(struct vfs_handle_struct *handle
 						off_t src_off,
 						struct files_struct *dest_fsp,
 						off_t dest_off,
-						off_t num)
+						off_t num,
+						uint32_t flags)
 {
 	struct tevent_req *req, *subreq;
 	struct fruit_copy_chunk_state *fruit_copy_chunk_state;
@@ -5283,7 +5284,8 @@ static struct tevent_req *fruit_copy_chunk_send(struct vfs_handle_struct *handle
 					      src_off,
 					      dest_fsp,
 					      dest_off,
-					      to_copy);
+					      to_copy,
+					      flags);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 6614fbb..4c2eb87 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1889,12 +1889,14 @@ static struct tevent_req *smb_full_audit_copy_chunk_send(struct vfs_handle_struc
 							 off_t src_off,
 							 struct files_struct *dest_fsp,
 							 off_t dest_off,
-							 off_t num)
+							 off_t num,
+							 uint32_t flags)
 {
 	struct tevent_req *req;
 
 	req = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp,
-					   src_off, dest_fsp, dest_off, num);
+					   src_off, dest_fsp, dest_off, num,
+					   flags);
 
 	do_log(SMB_VFS_OP_COPY_CHUNK_SEND, req, handle, "");
 
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 2ac3d97..52bd00e 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -1886,7 +1886,8 @@ static struct tevent_req *smb_time_audit_copy_chunk_send(struct vfs_handle_struc
 							 off_t src_off,
 							 struct files_struct *dest_fsp,
 							 off_t dest_off,
-							 off_t num)
+							 off_t num,
+							 uint32_t flags)
 {
 	struct tevent_req *req;
 	struct tevent_req *subreq;
@@ -1901,7 +1902,7 @@ static struct tevent_req *smb_time_audit_copy_chunk_send(struct vfs_handle_struc
 	clock_gettime_mono(&cc_state->ts_send);
 	subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, cc_state, ev,
 					      src_fsp, src_off,
-					      dest_fsp, dest_off, num);
+					      dest_fsp, dest_off, num, flags);
 	if (tevent_req_nomem(subreq, req)) {
 		return tevent_req_post(req, ev);
 	}
diff --git a/source3/smbd/smb2_ioctl_filesys.c b/source3/smbd/smb2_ioctl_filesys.c
index 64b5454..fbff97c 100644
--- a/source3/smbd/smb2_ioctl_filesys.c
+++ b/source3/smbd/smb2_ioctl_filesys.c
@@ -31,6 +31,275 @@
 #include "librpc/gen_ndr/ndr_ioctl.h"
 #include "smb2_ioctl_private.h"
 
+/*
+ * XXX this may reduce dup_extents->byte_count so that it's less than the
+ * target file size.
+ */
+static NTSTATUS fsctl_dup_extents_check_lengths(struct files_struct *src_fsp,
+						struct files_struct *dst_fsp,
+				struct fsctl_dup_extents_to_file *dup_extents)
+{
+	NTSTATUS status;
+
+	if ((dup_extents->source_off + dup_extents->byte_count
+						< dup_extents->source_off)
+	 || (dup_extents->target_off + dup_extents->byte_count
+						< dup_extents->target_off)) {
+		return NT_STATUS_INVALID_PARAMETER;	/* wrap */
+	}
+
+	status = vfs_stat_fsp(src_fsp);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/*
+	 * XXX vfs_btrfs and vfs_default have size checks in the copychunk
+	 * handler, as this needs to be rechecked after the src has potentially
+	 * been extended by a previous chunk in the compound copychunk req.
+	 */
+	if (src_fsp->fsp_name->st.st_ex_size
+			< dup_extents->source_off + dup_extents->byte_count) {
+		DEBUG(2, ("dup_extents req exceeds src size\n"));
+		return NT_STATUS_NOT_SUPPORTED;
+	}
+
+	status = vfs_stat_fsp(dst_fsp);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	if (dst_fsp->fsp_name->st.st_ex_size
+			< dup_extents->target_off + dup_extents->byte_count) {
+
+		if (dst_fsp->fsp_name->st.st_ex_size - dup_extents->target_off
+					> dst_fsp->fsp_name->st.st_ex_size) {
+			return NT_STATUS_INVALID_PARAMETER;	/* wrap */
+		}
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list