vfs: Add flags and xferlen args to SMB_VFS_OFFLOAD_READ_RECV
authorRalph Boehme <slow@samba.org>
Tue, 22 Jun 2021 18:13:02 +0000 (20:13 +0200)
committerJeremy Allison <jra@samba.org>
Fri, 8 Oct 2021 19:28:32 +0000 (19:28 +0000)
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 <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
13 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_btrfs.c
source3/modules/vfs_default.c
source3/modules/vfs_fruit.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_not_implemented.c
source3/modules/vfs_time_audit.c
source3/smbd/smb2_ioctl_filesys.c
source3/smbd/smb2_ioctl_network_fs.c
source3/smbd/vfs.c

index f393332c68142ae6520e8a95e56651781a81b8ca..cc7bb880d5c27069d71329632450a5a4069b00bd 100644 (file)
@@ -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;
index d6bf3171b952ba31556a1d17f9fc6219cbbba433..e145881b704381e54649fd1610a51e5e9340a76e 100644 (file)
@@ -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;
 }
index be7d47db957e9eab8de449d3202e857bd5744bea..da19ed406df363b977aeb6036d497491c5ee0796 100644 (file)
  * 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,
index 2ab5b4b56cc8d771047d97c8cbb33fc40d0d3512..49654f59ff245b43e01b9e78c8b30d99099c867b 100644 (file)
 #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))
index a31b232af4d3ed0d8890a8696fa2cf5f5311a754..53e6a3fd7c74e068156172f5cc9fd1e21058d8f1 100644 (file)
@@ -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);
 
index 37e9721c72b842595b82203290aeffe49620d432..18634fbf506ea72a954234fe3b41a52677cd8ae6 100644 (file)
@@ -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);
 
index ce42202b4a3421d3e14bc1fd5e17133365cbe02f..aeaddc5f7964f47992ba7a23aeb3ff316f5bd9ad 100644 (file)
@@ -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);
 
index 3852d729d86a2e214ba3f6dbd54325b975b0628b..2c07eab69ca4a897ac8faefbc8461d11012dcc5f 100644 (file)
@@ -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, "");
 
index 41f16869b3795febcba71e1274b882579da44c8e..cab132d57602b77624c8a0e4a91a2d8be01e6541 100644 (file)
@@ -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;
index 126cf5ba69b0959ece1558787c244d36da3f6aa6..8becd160456ae06ccb0e59d557fec7cc99369f94 100644 (file)
@@ -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);
 
index f5c472c2cd18e072d3989ece2d753ea0a3eb51bd..3324afbffc859dfe60ac62f235531b5f3af583e0 100644 (file)
@@ -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;
        }
index e0beb6c96fe8317b85b5472507b7cf1861e714ca..5b396855ca620086c25580aa94ed05eb8adfa221 100644 (file)
@@ -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)) {
index ddea7b16d15c1c2f32b8acecdfb84222f69f30ef..4c77dec2d32222af1fc7bf467d18286dfc875554 100644 (file)
@@ -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,