[PATCH 3/3] vfs_btrfs: pass-through copy-chunk(len=0) requests

David Disseldorp ddiss at samba.org
Thu Feb 6 12:12:22 MST 2014


Never map copy-chunk(len=0) requests to BTRFS_IOC_CLONE_RANGE ioctls. A
BTRFS_IOC_CLONE_RANGE with @src_length=0 results in a clone of all data
from @src_offset->EOF!

BUG: https://bugzilla.samba.org/show_bug.cgi?id=10424

Signed-off-by: David Disseldorp <ddiss at samba.org>
---
 source3/modules/vfs_btrfs.c | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c
index 2254fa2..997a5de 100644
--- a/source3/modules/vfs_btrfs.c
+++ b/source3/modules/vfs_btrfs.c
@@ -84,6 +84,27 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 	}
 	cc_state->handle = handle;
 
+	if (num == 0) {
+		/*
+		 * With a @src_length of zero, BTRFS_IOC_CLONE_RANGE clones
+		 * all data from @src_offset->EOF! This is certainly not what
+		 * the caller expects, and not what vfs_default does.
+		 */
+		cc_state->subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle,
+								cc_state, ev,
+								src_fsp,
+								src_off,
+								dest_fsp,
+								dest_off, num);
+		if (tevent_req_nomem(cc_state->subreq, req)) {
+			return tevent_req_post(req, ev);
+		}
+		tevent_req_set_callback(cc_state->subreq,
+					btrfs_copy_chunk_done,
+					req);
+		return req;
+	}
+
 	status = vfs_stat_fsp(src_fsp);
 	if (tevent_req_nterror(req, status)) {
 		return tevent_req_post(req, ev);
@@ -155,7 +176,6 @@ static struct tevent_req *btrfs_copy_chunk_send(struct vfs_handle_struct *handle
 					btrfs_copy_chunk_done,
 					req);
 		return req;
-
 	}
 
 	DEBUG(5, ("BTRFS_IOC_CLONE_RANGE returned %d\n", ret));
-- 
1.8.4.5



More information about the samba-technical mailing list