From: Ralph Boehme Date: Tue, 22 Jun 2021 18:13:02 +0000 (+0200) Subject: vfs: Add flags and xferlen args to SMB_VFS_OFFLOAD_READ_RECV X-Git-Tag: ldb-2.5.0~498 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8fa7848b4a002900e0c3384d2e0d41ea0fdf6ea9;p=thirdparty%2Fsamba.git vfs: Add flags and xferlen args to SMB_VFS_OFFLOAD_READ_RECV We missed these values which follow from MS-FSCC 2.3.80 “FSCTL_OFFLOAD_READ Reply”: Flags (4 bytes): A 32-bit unsigned integer that indicates which flags were returned for this operation. Possible values for the flags follow. All unused bits are reserved for future use, SHOULD be set to 0, and MUST be ignored. OFFLOAD_READ_FLAG_ALL_ZERO_BEYOND_CURRENT_RANGE (0x00000001) => The data beyond the current range is logically equivalent to zero. TransferLength (8 bytes): A 64-bit unsigned integer that contains the amount, in bytes, of data that the Token logically represents. This value indicates a contiguous region of the file from the beginning of the requested offset in the FileOffset field in the FSCTL_OFFLOAD_READ_INPUT data element (section 2.3.79). This value can be smaller than the CopyLength field specified in the FSCTL_OFFLOAD_READ_INPUT data element, which indicates that less data was logically represented (logically read) with the Token than was requested. The value of this field MUST be greater than 0x0000000000000000 and MUST be aligned to a logical sector boundary on the volume. As we currently only implement COPY_CHUNK over the OFFLOAD VFS interface, the VFS COPY_CHUNK backend in vfs_default just sets both values to 0 and they are unused in the SMB frontend. Signed-off-by: Ralph Boehme Reviewed-by: Jeremy Allison --- diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index f393332c681..cc7bb880d5c 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -560,6 +560,8 @@ static struct tevent_req *skel_offload_read_send( static NTSTATUS skel_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *_token_blob) { NTSTATUS status; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index d6bf3171b95..e145881b704 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -667,6 +667,8 @@ static uint64_t skel_fs_file_id(vfs_handle_struct *handle, struct skel_offload_read_state { struct vfs_handle_struct *handle; + uint32_t flags; + uint64_t xferlen; DATA_BLOB token; }; @@ -714,6 +716,8 @@ static void skel_offload_read_done(struct tevent_req *subreq) status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(subreq, state->handle, state, + &state->flags, + &state->xferlen, &state->token); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { @@ -727,6 +731,8 @@ static void skel_offload_read_done(struct tevent_req *subreq) static NTSTATUS skel_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *_token) { struct skel_offload_read_state *state = tevent_req_data( @@ -749,6 +755,8 @@ static NTSTATUS skel_offload_read_recv(struct tevent_req *req, return NT_STATUS_NO_MEMORY; } + *flags = state->flags; + *xferlen = state->xferlen; *_token = token; return NT_STATUS_OK; } diff --git a/source3/include/vfs.h b/source3/include/vfs.h index be7d47db957..da19ed406df 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -361,6 +361,7 @@ * Version 45 - Add SMB_VFS_FCHFLAGS * Version 45 - Remove SMB_VFS_GETXATTR * Version 46 - Rename SMB_VFS_KERNEL_FLOCK to SMB_VFS_FILESYSTEM_SHAREMODE + * Version 46 - Add flags and xferlen args to SMB_VFS_OFFLOAD_READ_RECV */ #define SMB_VFS_INTERFACE_VERSION 46 @@ -1089,6 +1090,8 @@ struct vfs_fn_pointers { NTSTATUS (*offload_read_recv_fn)(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token_blob); struct tevent_req *(*offload_write_send_fn)(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, @@ -1659,6 +1662,8 @@ struct tevent_req *smb_vfs_call_offload_read_send( NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token_blob); struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, @@ -2024,6 +2029,8 @@ struct tevent_req *vfs_not_implemented_offload_read_send( NTSTATUS vfs_not_implemented_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *_token_blob); struct tevent_req *vfs_not_implemented_offload_write_send( struct vfs_handle_struct *handle, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 2ab5b4b56cc..49654f59ff2 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -431,10 +431,10 @@ #define SMB_VFS_NEXT_OFFLOAD_READ_SEND(mem_ctx, ev, handle, fsp, fsctl, ttl, offset, to_copy) \ smb_vfs_call_offload_read_send((mem_ctx), (ev), (handle)->next, (fsp), (fsctl), (ttl), (offset), (to_copy)) -#define SMB_VFS_OFFLOAD_READ_RECV(req, conn, mem_ctx, token_blob) \ - smb_vfs_call_offload_read_recv((req), (conn)->vfs_handles, (mem_ctx), (token_blob)) -#define SMB_VFS_NEXT_OFFLOAD_READ_RECV(req, handle, mem_ctx, token_blob) \ - smb_vfs_call_offload_read_recv((req), (handle)->next, (mem_ctx), (token_blob)) +#define SMB_VFS_OFFLOAD_READ_RECV(req, conn, mem_ctx, flags, xferlen, token_blob) \ + smb_vfs_call_offload_read_recv((req), (conn)->vfs_handles, (mem_ctx), (flags), (xferlen), (token_blob)) +#define SMB_VFS_NEXT_OFFLOAD_READ_RECV(req, handle, mem_ctx, flags, xferlen, token_blob) \ + smb_vfs_call_offload_read_recv((req), (handle)->next, (mem_ctx), flags, xferlen, (token_blob)) #define SMB_VFS_OFFLOAD_WRITE_SEND(conn, mem_ctx, ev, fsctl, token, transfer_offset, dest_fsp, dest_off, num) \ smb_vfs_call_offload_write_send((conn)->vfs_handles, (mem_ctx), (ev), (fsctl), (token), (transfer_offset), (dest_fsp), (dest_off), (num)) diff --git a/source3/modules/vfs_btrfs.c b/source3/modules/vfs_btrfs.c index a31b232af4d..53e6a3fd7c7 100644 --- a/source3/modules/vfs_btrfs.c +++ b/source3/modules/vfs_btrfs.c @@ -86,6 +86,8 @@ static struct vfs_offload_ctx *btrfs_offload_ctx; struct btrfs_offload_read_state { struct vfs_handle_struct *handle; files_struct *fsp; + uint32_t flags; + uint64_t xferlen; DATA_BLOB token; }; @@ -158,6 +160,8 @@ static void btrfs_offload_read_done(struct tevent_req *subreq) status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(subreq, state->handle, state, + &state->flags, + &state->xferlen, &state->token); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { @@ -178,6 +182,8 @@ static void btrfs_offload_read_done(struct tevent_req *subreq) static NTSTATUS btrfs_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token) { struct btrfs_offload_read_state *state = tevent_req_data( @@ -189,6 +195,8 @@ static NTSTATUS btrfs_offload_read_recv(struct tevent_req *req, return status; } + *flags = state->flags; + *xferlen = state->xferlen; token->length = state->token.length; token->data = talloc_move(mem_ctx, &state->token.data); diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 37e9721c72b..18634fbf506 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -1990,6 +1990,8 @@ static struct tevent_req *vfswrap_offload_read_send( static NTSTATUS vfswrap_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token) { struct vfswrap_offload_read_state *state = tevent_req_data( @@ -2001,6 +2003,8 @@ static NTSTATUS vfswrap_offload_read_recv(struct tevent_req *req, return status; } + *flags = 0; + *xferlen = 0; token->length = state->token.length; token->data = talloc_move(mem_ctx, &state->token.data); diff --git a/source3/modules/vfs_fruit.c b/source3/modules/vfs_fruit.c index ce42202b4a3..aeaddc5f796 100644 --- a/source3/modules/vfs_fruit.c +++ b/source3/modules/vfs_fruit.c @@ -4486,6 +4486,8 @@ struct fruit_offload_read_state { struct tevent_context *ev; files_struct *fsp; uint32_t fsctl; + uint32_t flags; + uint64_t xferlen; DATA_BLOB token; }; @@ -4537,6 +4539,8 @@ static void fruit_offload_read_done(struct tevent_req *subreq) status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(subreq, state->handle, state, + &state->flags, + &state->xferlen, &state->token); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { @@ -4568,6 +4572,8 @@ static void fruit_offload_read_done(struct tevent_req *subreq) static NTSTATUS fruit_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token) { struct fruit_offload_read_state *state = tevent_req_data( @@ -4579,6 +4585,8 @@ static NTSTATUS fruit_offload_read_recv(struct tevent_req *req, return status; } + *flags = state->flags; + *xferlen = state->xferlen; token->length = state->token.length; token->data = talloc_move(mem_ctx, &state->token.data); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 3852d729d86..2c07eab69ca 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -2234,12 +2234,14 @@ static NTSTATUS smb_full_audit_offload_read_recv( struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *_token_blob) { NTSTATUS status; status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(req, handle, mem_ctx, - _token_blob); + flags, xferlen, _token_blob); do_log(SMB_VFS_OP_OFFLOAD_READ_RECV, NT_STATUS_IS_OK(status), handle, ""); diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c index 41f16869b37..cab132d5760 100644 --- a/source3/modules/vfs_not_implemented.c +++ b/source3/modules/vfs_not_implemented.c @@ -559,6 +559,8 @@ struct tevent_req *vfs_not_implemented_offload_read_send( NTSTATUS vfs_not_implemented_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *_token_blob) { NTSTATUS status; diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 126cf5ba69b..8becd160456 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -2031,6 +2031,8 @@ static NTSTATUS smb_time_fset_dos_attributes(struct vfs_handle_struct *handle, struct time_audit_offload_read_state { struct vfs_handle_struct *handle; struct timespec ts_send; + uint32_t flags; + uint64_t xferlen; DATA_BLOB token_blob; }; @@ -2081,6 +2083,8 @@ static void smb_time_audit_offload_read_done(struct tevent_req *subreq) status = SMB_VFS_NEXT_OFFLOAD_READ_RECV(subreq, state->handle, state, + &state->flags, + &state->xferlen, &state->token_blob); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { @@ -2093,6 +2097,8 @@ static NTSTATUS smb_time_audit_offload_read_recv( struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token_blob) { struct time_audit_offload_read_state *state = tevent_req_data( @@ -2112,6 +2118,8 @@ static NTSTATUS smb_time_audit_offload_read_recv( return status; } + *flags = state->flags; + *xferlen = state->xferlen; token_blob->length = state->token_blob.length; token_blob->data = talloc_move(mem_ctx, &state->token_blob.data); diff --git a/source3/smbd/smb2_ioctl_filesys.c b/source3/smbd/smb2_ioctl_filesys.c index f5c472c2cd1..3324afbffc8 100644 --- a/source3/smbd/smb2_ioctl_filesys.c +++ b/source3/smbd/smb2_ioctl_filesys.c @@ -254,11 +254,17 @@ static void fsctl_dup_extents_offload_read_done(struct tevent_req *subreq) subreq, struct tevent_req); struct fsctl_dup_extents_state *state = tevent_req_data( req, struct fsctl_dup_extents_state); + uint32_t flags; + uint64_t xferlen; DATA_BLOB token; NTSTATUS status; + /* + * Note that both flags and xferlen are not used with copy-chunk. + */ + status = SMB_VFS_OFFLOAD_READ_RECV(subreq, state->dst_fsp->conn, - state, &token); + state, &flags, &xferlen, &token); if (tevent_req_nterror(req, status)) { return; } diff --git a/source3/smbd/smb2_ioctl_network_fs.c b/source3/smbd/smb2_ioctl_network_fs.c index e0beb6c96fe..5b396855ca6 100644 --- a/source3/smbd/smb2_ioctl_network_fs.c +++ b/source3/smbd/smb2_ioctl_network_fs.c @@ -769,12 +769,19 @@ static void smb2_ioctl_network_fs_offload_read_done(struct tevent_req *subreq) req, struct smbd_smb2_ioctl_state); struct req_resume_key_rsp rkey_rsp; enum ndr_err_code ndr_ret; + uint32_t flags; + uint64_t xferlen; DATA_BLOB token; NTSTATUS status; + /* + * Note that both flags and xferlen are not used with copy-chunk. + */ status = SMB_VFS_OFFLOAD_READ_RECV(subreq, state->fsp->conn, state, + &flags, + &xferlen, &token); TALLOC_FREE(subreq); if (tevent_req_nterror(req, status)) { diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index ddea7b16d15..4c77dec2d32 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2516,10 +2516,12 @@ struct tevent_req *smb_vfs_call_offload_read_send(TALLOC_CTX *mem_ctx, NTSTATUS smb_vfs_call_offload_read_recv(struct tevent_req *req, struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, + uint32_t *flags, + uint64_t *xferlen, DATA_BLOB *token_blob) { VFS_FIND(offload_read_recv); - return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, token_blob); + return handle->fns->offload_read_recv_fn(req, handle, mem_ctx, flags, xferlen, token_blob); } struct tevent_req *smb_vfs_call_offload_write_send(struct vfs_handle_struct *handle,