s3-vfs: add copy_chunk vfs hooks
authorDavid Disseldorp <ddiss@suse.de>
Tue, 15 Jan 2013 16:22:59 +0000 (17:22 +0100)
committerDavid Disseldorp <ddiss@samba.org>
Mon, 15 Apr 2013 16:15:13 +0000 (18:15 +0200)
copy_chunk copies n bytes from a source file at a specific offset to a
destination file at a given offset. This interface will be used in
handling smb2 FSCTL_SRV_COPYCHUNK ioctl requests.

Use a pread/pwrite loop in vfs_default, so that requests referring to
the same src and dest file are possible.

Provide send and receive hooks for copy chunk VFS interface, allowing
asynchronous behaviour.

Check whether the request source offset + length exceeds the current
size. Return STATUS_INVALID_VIEW_SIZE under such a condition, matching
Windows server behaviour.

(cherry picked from commit ef00eb90e56dfac2d823582cec92abf1fa9905f1)

docs-xml/manpages/vfs_full_audit.8.xml
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_time_audit.c
source3/smbd/vfs.c

index a44924a8f64293c439e09d680e5f76ef6d17ba4d..312bc25078d00e38c0189db12493a66cb9d67b96 100644 (file)
@@ -46,6 +46,8 @@
         <member>close</member>
         <member>closedir</member>
         <member>connect</member>
+       <member>copy_chunk_send</member>
+       <member>copy_chunk_recv</member>
         <member>disconnect</member>
         <member>disk_free</member>
         <member>fchmod</member>
index e66d7aa5cb45c52617d837fb05d257d4edc694b1..f0aff08b50f3255a4ded6e26b9bfba78ed0de97e 100644 (file)
@@ -23,6 +23,7 @@
 
 
 #include "../source3/include/includes.h"
+#include "lib/util/tevent_ntstatus.h"
 
 /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE 
    SAMBA DEVELOPERS GUIDE!!!!!!
@@ -452,6 +453,45 @@ static struct file_id skel_file_id_create(vfs_handle_struct *handle,
        return id;
 }
 
+struct skel_cc_state {
+       uint64_t unused;
+};
+static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle,
+                                              TALLOC_CTX *mem_ctx,
+                                              struct tevent_context *ev,
+                                              struct files_struct *src_fsp,
+                                              off_t src_off,
+                                              struct files_struct *dest_fsp,
+                                              off_t dest_off,
+                                              off_t num)
+{
+       struct tevent_req *req;
+       struct skel_cc_state *cc_state;
+
+       req = tevent_req_create(mem_ctx, &cc_state, struct skel_cc_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       tevent_req_nterror(req, NT_STATUS_NOT_IMPLEMENTED);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS skel_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                    struct tevent_req *req,
+                                    off_t *copied)
+{
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+       tevent_req_received(req);
+
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle,
                                struct files_struct *fsp,
                                const char *fname,
@@ -767,6 +807,8 @@ struct vfs_fn_pointers skel_opaque_fns = {
        .notify_watch_fn = skel_notify_watch,
        .chflags_fn = skel_chflags,
        .file_id_create_fn = skel_file_id_create,
+       .copy_chunk_send_fn = skel_copy_chunk_send,
+       .copy_chunk_recv_fn = skel_copy_chunk_recv,
 
        .streaminfo_fn = skel_streaminfo,
        .get_real_filename_fn = skel_get_real_filename,
index 0c84e19fcd117031442484e10ff6b3ff2407a9ef..4085768f1cd40f1d3fd213c25f23a7e64e67af37 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "../source3/include/includes.h"
 #include "lib/util/tevent_unix.h"
+#include "lib/util/tevent_ntstatus.h"
 
 /* PLEASE,PLEASE READ THE VFS MODULES CHAPTER OF THE 
    SAMBA DEVELOPERS GUIDE!!!!!!
@@ -541,6 +542,78 @@ static struct file_id skel_file_id_create(vfs_handle_struct *handle,
        return SMB_VFS_NEXT_FILE_ID_CREATE(handle, sbuf);
 }
 
+struct skel_cc_state {
+       struct vfs_handle_struct *handle;
+       off_t copied;
+};
+static void skel_copy_chunk_done(struct tevent_req *subreq);
+
+static struct tevent_req *skel_copy_chunk_send(struct vfs_handle_struct *handle,
+                                              TALLOC_CTX *mem_ctx,
+                                              struct tevent_context *ev,
+                                              struct files_struct *src_fsp,
+                                              off_t src_off,
+                                              struct files_struct *dest_fsp,
+                                              off_t dest_off,
+                                              off_t num)
+{
+       struct tevent_req *req;
+       struct tevent_req *subreq;
+       struct skel_cc_state *cc_state;
+
+       req = tevent_req_create(mem_ctx, &cc_state, struct skel_cc_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       cc_state->handle = handle;
+       subreq = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, cc_state, ev,
+                                             src_fsp, src_off,
+                                             dest_fsp, dest_off, num);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_set_callback(subreq, skel_copy_chunk_done, req);
+       return req;
+}
+
+static void skel_copy_chunk_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct skel_cc_state *cc_state
+                       = tevent_req_data(req, struct skel_cc_state);
+       NTSTATUS status;
+
+       status = SMB_VFS_NEXT_COPY_CHUNK_RECV(cc_state->handle,
+                                             subreq,
+                                             &cc_state->copied);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS skel_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                    struct tevent_req *req,
+                                    off_t *copied)
+{
+       struct skel_cc_state *cc_state
+                       = tevent_req_data(req, struct skel_cc_state);
+       NTSTATUS status;
+
+       *copied = cc_state->copied;
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+
+       tevent_req_received(req);
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS skel_streaminfo(struct vfs_handle_struct *handle,
                                struct files_struct *fsp,
                                const char *fname,
@@ -869,6 +942,8 @@ struct vfs_fn_pointers skel_transparent_fns = {
        .notify_watch_fn = skel_notify_watch,
        .chflags_fn = skel_chflags,
        .file_id_create_fn = skel_file_id_create,
+       .copy_chunk_send_fn = skel_copy_chunk_send,
+       .copy_chunk_recv_fn = skel_copy_chunk_recv,
 
        .streaminfo_fn = skel_streaminfo,
        .get_real_filename_fn = skel_get_real_filename,
index 2992c1db32167f0db182960b1968d67a51b06eb2..2805c1e7a10d3c83986cbef4c9fb2fd9a8241b09 100644 (file)
 /* Bump to version 30 - Samba 4.0.0 will ship with interface version 30 */
 /* Leave at 30 - not yet released. Added conn->cwd to save vfs_GetWd() calls. */
 /* Leave at 30 - not yet released. Changed sys_acl_blob_get_file interface to remove type */
+/* Leave at 30 - not yet released. add SMB_VFS_COPY_CHUNK() */
 #define SMB_VFS_INTERFACE_VERSION 30
 
 /*
@@ -609,6 +610,17 @@ struct vfs_fn_pointers {
        int (*chflags_fn)(struct vfs_handle_struct *handle, const char *path, unsigned int flags);
        struct file_id (*file_id_create_fn)(struct vfs_handle_struct *handle,
                                            const SMB_STRUCT_STAT *sbuf);
+       struct tevent_req *(*copy_chunk_send_fn)(struct vfs_handle_struct *handle,
+                                                TALLOC_CTX *mem_ctx,
+                                                struct tevent_context *ev,
+                                                struct files_struct *src_fsp,
+                                                off_t src_off,
+                                                struct files_struct *dest_fsp,
+                                                off_t dest_off,
+                                                off_t num);
+       NTSTATUS (*copy_chunk_recv_fn)(struct vfs_handle_struct *handle,
+                                      struct tevent_req *req,
+                                      off_t *copied);
 
        NTSTATUS (*streaminfo_fn)(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
@@ -1080,7 +1092,18 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
                            uint32_t in_len,
                            uint8_t **_out_data,
                            uint32_t max_out_len,
-                           uint32_t *out_len); 
+                           uint32_t *out_len);
+struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               struct files_struct *src_fsp,
+                                               off_t src_off,
+                                               struct files_struct *dest_fsp,
+                                               off_t dest_off,
+                                               off_t num);
+NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req,
+                                     off_t *copied);
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
                                  uint32 security_info,
index 331fe001be67e05120b127a16a0f1fdc4d6bd832..364a4ca6e1a8190bb0b981be535a385d9f316176 100644 (file)
 #define SMB_VFS_NEXT_FSCTL(handle, fsp, ctx, function, req_flags, in_data, in_len, out_data, max_out_len, out_len) \
        smb_vfs_call_fsctl((handle)->next, (fsp), (ctx), (function), (req_flags), (in_data), (in_len), (out_data), (max_out_len), (out_len))
 
+#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_RECV(conn, req, copied) \
+       smb_vfs_call_copy_chunk_recv((conn)->vfs_handles, (req), (copied))
+#define SMB_VFS_NEXT_COPY_CHUNK_RECV(handle, req, copied) \
+       smb_vfs_call_copy_chunk_recv((handle)->next, (req), (copied))
+
 #define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc)               \
                smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc))
 #define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \
index 75dd5acc7795a7d84e27558cf72d44b83b0937eb..a44f99fe19df7ac10bec00fa4cb75dcd167c5c5c 100644 (file)
@@ -31,6 +31,7 @@
 #include "librpc/gen_ndr/ndr_dfsblobs.h"
 #include "lib/util/tevent_unix.h"
 #include "lib/asys/asys.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -1323,6 +1324,114 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
        return NT_STATUS_NOT_SUPPORTED;
 }
 
+struct vfs_cc_state {
+       off_t copied;
+       uint8_t buf[65536];
+};
+
+static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *handle,
+                                                 TALLOC_CTX *mem_ctx,
+                                                 struct tevent_context *ev,
+                                                 struct files_struct *src_fsp,
+                                                 off_t src_off,
+                                                 struct files_struct *dest_fsp,
+                                                 off_t dest_off,
+                                                 off_t num)
+{
+       struct tevent_req *req;
+       struct vfs_cc_state *vfs_cc_state;
+       NTSTATUS status;
+
+       DEBUG(10, ("performing server side copy chunk of length %lu\n",
+                  (unsigned long)num));
+
+       req = tevent_req_create(mem_ctx, &vfs_cc_state, struct vfs_cc_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       status = vfs_stat_fsp(src_fsp);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
+       if (src_fsp->fsp_name->st.st_ex_size < src_off + num) {
+               /*
+                * [MS-SMB2] 3.3.5.15.6 Handling a Server-Side Data Copy Request
+                *   If the SourceOffset or SourceOffset + Length extends beyond
+                *   the end of file, the server SHOULD<240> treat this as a
+                *   STATUS_END_OF_FILE error.
+                * ...
+                *   <240> Section 3.3.5.15.6: Windows servers will return
+                *   STATUS_INVALID_VIEW_SIZE instead of STATUS_END_OF_FILE.
+                */
+               tevent_req_nterror(req, NT_STATUS_INVALID_VIEW_SIZE);
+               return tevent_req_post(req, ev);
+       }
+
+       /* could use 2.6.33+ sendfile here to do this in kernel */
+       while (vfs_cc_state->copied < num) {
+               ssize_t ret;
+               off_t this_num = MIN(sizeof(vfs_cc_state->buf),
+                                    num - vfs_cc_state->copied);
+
+               ret = SMB_VFS_PREAD(src_fsp, vfs_cc_state->buf,
+                                   this_num, src_off);
+               if (ret == -1) {
+                       tevent_req_nterror(req, map_nt_error_from_unix(errno));
+                       return tevent_req_post(req, ev);
+               }
+               if (ret != this_num) {
+                       /* zero tolerance for short reads */
+                       tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
+                       return tevent_req_post(req, ev);
+               }
+               src_off += ret;
+
+               ret = SMB_VFS_PWRITE(dest_fsp, vfs_cc_state->buf,
+                                    this_num, dest_off);
+               if (ret == -1) {
+                       tevent_req_nterror(req, map_nt_error_from_unix(errno));
+                       return tevent_req_post(req, ev);
+               }
+               if (ret != this_num) {
+                       /* zero tolerance for short writes */
+                       tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
+                       return tevent_req_post(req, ev);
+               }
+               dest_off += ret;
+
+               vfs_cc_state->copied += this_num;
+       }
+
+       tevent_req_done(req);
+       return tevent_req_post(req, ev);
+}
+
+static NTSTATUS vfswrap_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                       struct tevent_req *req,
+                                       off_t *copied)
+{
+       struct vfs_cc_state *vfs_cc_state = tevent_req_data(req,
+                                                       struct vfs_cc_state);
+       NTSTATUS status;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               DEBUG(2, ("server side copy chunk failed: %s\n",
+                         nt_errstr(status)));
+               *copied = 0;
+               tevent_req_received(req);
+               return status;
+       }
+
+       *copied = vfs_cc_state->copied;
+       DEBUG(10, ("server side copy chunk copied %lu\n",
+                  (unsigned long)*copied));
+       tevent_req_received(req);
+
+       return NT_STATUS_OK;
+}
+
 /********************************************************************
  Given a stat buffer return the allocated size on disk, taking into
  account sparse files.
@@ -2387,6 +2496,8 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .strict_unlock_fn = vfswrap_strict_unlock,
        .translate_name_fn = vfswrap_translate_name,
        .fsctl_fn = vfswrap_fsctl,
+       .copy_chunk_send_fn = vfswrap_copy_chunk_send,
+       .copy_chunk_recv_fn = vfswrap_copy_chunk_recv,
 
        /* NT ACL operations. */
 
index b1fb090dc670a24094327e4e5344b8e12773cdf4..549f55e189565ae88b17b9361ded488fa779338a 100644 (file)
@@ -161,6 +161,8 @@ typedef enum _vfs_op_type {
        SMB_VFS_OP_STRICT_LOCK,
        SMB_VFS_OP_STRICT_UNLOCK,
        SMB_VFS_OP_TRANSLATE_NAME,
+       SMB_VFS_OP_COPY_CHUNK_SEND,
+       SMB_VFS_OP_COPY_CHUNK_RECV,
 
        /* NT ACL operations. */
 
@@ -281,6 +283,8 @@ static struct {
        { SMB_VFS_OP_STRICT_LOCK, "strict_lock" },
        { SMB_VFS_OP_STRICT_UNLOCK, "strict_unlock" },
        { SMB_VFS_OP_TRANSLATE_NAME,    "translate_name" },
+       { SMB_VFS_OP_COPY_CHUNK_SEND,   "copy_chunk_send" },
+       { SMB_VFS_OP_COPY_CHUNK_RECV,   "copy_chunk_recv" },
        { SMB_VFS_OP_FGET_NT_ACL,       "fget_nt_acl" },
        { SMB_VFS_OP_GET_NT_ACL,        "get_nt_acl" },
        { SMB_VFS_OP_FSET_NT_ACL,       "fset_nt_acl" },
@@ -1732,6 +1736,38 @@ static NTSTATUS smb_full_audit_translate_name(struct vfs_handle_struct *handle,
        return result;
 }
 
+static struct tevent_req *smb_full_audit_copy_chunk_send(struct vfs_handle_struct *handle,
+                                                        TALLOC_CTX *mem_ctx,
+                                                        struct tevent_context *ev,
+                                                        struct files_struct *src_fsp,
+                                                        off_t src_off,
+                                                        struct files_struct *dest_fsp,
+                                                        off_t dest_off,
+                                                        off_t num)
+{
+       struct tevent_req *req;
+
+       req = SMB_VFS_NEXT_COPY_CHUNK_SEND(handle, mem_ctx, ev, src_fsp,
+                                          src_off, dest_fsp, dest_off, num);
+
+       do_log(SMB_VFS_OP_COPY_CHUNK_SEND, req, handle, "");
+
+       return req;
+}
+
+static NTSTATUS smb_full_audit_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                              struct tevent_req *req,
+                                              off_t *copied)
+{
+       NTSTATUS result;
+
+       result = SMB_VFS_NEXT_COPY_CHUNK_RECV(handle, req, copied);
+
+       do_log(SMB_VFS_OP_COPY_CHUNK_RECV, NT_STATUS_IS_OK(result), handle, "");
+
+       return result;
+}
+
 static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                           uint32 security_info,
                                           TALLOC_CTX *mem_ctx,
@@ -2131,6 +2167,8 @@ static struct vfs_fn_pointers vfs_full_audit_fns = {
        .strict_lock_fn = smb_full_audit_strict_lock,
        .strict_unlock_fn = smb_full_audit_strict_unlock,
        .translate_name_fn = smb_full_audit_translate_name,
+       .copy_chunk_send_fn = smb_full_audit_copy_chunk_send,
+       .copy_chunk_recv_fn = smb_full_audit_copy_chunk_recv,
        .fget_nt_acl_fn = smb_full_audit_fget_nt_acl,
        .get_nt_acl_fn = smb_full_audit_get_nt_acl,
        .fset_nt_acl_fn = smb_full_audit_fset_nt_acl,
index 95b4148232b369878c62a599d44d5b70358bddff..1b14d650afd3f07b1f5325acd15db93a634b187b 100644 (file)
@@ -29,6 +29,7 @@
 #include "smbd/smbd.h"
 #include "ntioctl.h"
 #include "lib/util/tevent_unix.h"
+#include "lib/util/tevent_ntstatus.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -1668,6 +1669,88 @@ static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle,
        return result;
 }
 
+struct time_audit_cc_state {
+       struct timespec ts_send;
+       struct vfs_handle_struct *handle;
+       off_t copied;
+};
+static void smb_time_audit_copy_chunk_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_time_audit_copy_chunk_send(struct vfs_handle_struct *handle,
+                                                        TALLOC_CTX *mem_ctx,
+                                                        struct tevent_context *ev,
+                                                        struct files_struct *src_fsp,
+                                                        off_t src_off,
+                                                        struct files_struct *dest_fsp,
+                                                        off_t dest_off,
+                                                        off_t num)
+{
+       struct tevent_req *req;
+       struct tevent_req *subreq;
+       struct time_audit_cc_state *cc_state;
+
+       req = tevent_req_create(mem_ctx, &cc_state, struct time_audit_cc_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       cc_state->handle = handle;
+       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);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_set_callback(subreq, smb_time_audit_copy_chunk_done, req);
+       return req;
+}
+
+static void smb_time_audit_copy_chunk_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct time_audit_cc_state *cc_state
+                       = tevent_req_data(req, struct time_audit_cc_state);
+       NTSTATUS status;
+
+       status = SMB_VFS_NEXT_COPY_CHUNK_RECV(cc_state->handle,
+                                             subreq,
+                                             &cc_state->copied);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+       tevent_req_done(req);
+}
+
+static NTSTATUS smb_time_audit_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                              struct tevent_req *req,
+                                              off_t *copied)
+{
+       struct time_audit_cc_state *cc_state
+                       = tevent_req_data(req, struct time_audit_cc_state);
+       struct timespec ts_recv;
+       double timediff;
+       NTSTATUS status;
+
+       clock_gettime_mono(&ts_recv);
+       timediff = nsec_time_diff(&ts_recv, &cc_state->ts_send)*1.0e-9;
+       if (timediff > audit_timeout) {
+               smb_time_audit_log("copy_chunk", timediff);
+       }
+
+       *copied = cc_state->copied;
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+
+       tevent_req_received(req);
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle,
                                           files_struct *fsp,
                                           uint32 security_info,
@@ -2179,6 +2262,8 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
        .strict_lock_fn = smb_time_audit_strict_lock,
        .strict_unlock_fn = smb_time_audit_strict_unlock,
        .translate_name_fn = smb_time_audit_translate_name,
+       .copy_chunk_send_fn = smb_time_audit_copy_chunk_send,
+       .copy_chunk_recv_fn = smb_time_audit_copy_chunk_recv,
        .fget_nt_acl_fn = smb_time_audit_fget_nt_acl,
        .get_nt_acl_fn = smb_time_audit_get_nt_acl,
        .fset_nt_acl_fn = smb_time_audit_fset_nt_acl,
index 581a02567ec09342b7c0056b197ebe39afe1b57e..b81e8ded3f9c679e093d57723dc64df0e048ac20 100644 (file)
@@ -2157,11 +2157,33 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle,
                            uint32_t *out_len)
 {
        VFS_FIND(fsctl);
-       return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags, 
-                                    in_data, in_len, out_data, max_out_len, 
+       return handle->fns->fsctl_fn(handle, fsp, ctx, function, req_flags,
+                                    in_data, in_len, out_data, max_out_len,
                                     out_len);
 }
 
+struct tevent_req *smb_vfs_call_copy_chunk_send(struct vfs_handle_struct *handle,
+                                               TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               struct files_struct *src_fsp,
+                                               off_t src_off,
+                                               struct files_struct *dest_fsp,
+                                               off_t dest_off,
+                                               off_t num)
+{
+       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);
+}
+
+NTSTATUS smb_vfs_call_copy_chunk_recv(struct vfs_handle_struct *handle,
+                                     struct tevent_req *req,
+                                     off_t *copied)
+{
+       VFS_FIND(copy_chunk_recv);
+       return handle->fns->copy_chunk_recv_fn(handle, req, copied);
+}
+
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
                                  uint32 security_info,