From: Aurelien Aptel Date: Mon, 24 Aug 2015 16:22:56 +0000 (+0200) Subject: vfs: add parameter to copy chunk VFS function to handle dup_extents X-Git-Tag: ldb-1.1.30~247 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=fc2b3662b813e936458860c3c041ee50e5dd1a88 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 Signed-off-by: David Disseldorp Reviewed-by: Ralph Böhme --- diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index ffd951c0e2d..af119f32db1 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 afadbc1a5cd..e9745292730 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 f6df93a6acf..fd493e4d03b 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,17 @@ 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_MASK_ALL = 0x0001, +}; + struct vfs_aio_state { int error; uint64_t duration; @@ -709,7 +721,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 +1254,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 40c93f8a3b3..0cbcf89cce5 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 ab4fd99ba2c..bf0a080b6ce 100644 --- a/source3/modules/vfs_btrfs.c +++ b/source3/modules/vfs_btrfs.c @@ -92,7 +92,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 +107,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 +126,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); } @@ -196,7 +204,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 d6601205610..ffdc40ae87e 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1616,7 +1616,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 +1631,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, diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index 273540e1c30..ee8cdb783f7 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 6614fbba903..4c2eb87ddb1 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 2ac3d97a200..52bd00edb13 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_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c index 5b869ec7311..7b496ef796f 100644 --- a/source3/smbd/smb2_ioctl_network_fs.c +++ b/source3/smbd/smb2_ioctl_network_fs.c @@ -347,6 +347,7 @@ static NTSTATUS fsctl_srv_copychunk_loop(struct tevent_req *req) 0, state->dst_fsp, 0, + 0, 0); if (subreq == NULL) { return NT_STATUS_NO_MEMORY; @@ -366,7 +367,8 @@ static NTSTATUS fsctl_srv_copychunk_loop(struct tevent_req *req) chunk->source_off, state->dst_fsp, chunk->target_off, - length); + length, + 0); if (tevent_req_nomem(subreq, req)) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index f75172a45cf..560c4b217a4 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2305,11 +2305,13 @@ 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) { VFS_FIND(copy_chunk_send); return handle->fns->copy_chunk_send_fn(handle, mem_ctx, ev, src_fsp, - src_off, dest_fsp, dest_off, num); + src_off, dest_fsp, dest_off, num, + flags); } NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,