lib: modules: Change XXX_init interface from XXX_init(void) to XXX_init(TALLOC_CTX *)
[metze/samba-autobuild/.git] / source3 / modules / vfs_default.c
index 9b434a0dfd59f79f16299c4ed4c12216f0236692..d660120561024b195f622e142456e55f4cb17dc2 100644 (file)
 #include "source3/include/msdfs.h"
 #include "librpc/gen_ndr/ndr_dfsblobs.h"
 #include "lib/util/tevent_unix.h"
-#include "lib/asys/asys.h"
 #include "lib/util/tevent_ntstatus.h"
-#include "lib/sys_rw.h"
+#include "lib/util/sys_rw.h"
+#include "lib/pthreadpool/pthreadpool_tevent.h"
+#include "librpc/gen_ndr/ndr_ioctl.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_VFS
@@ -58,19 +59,23 @@ static uint64_t vfswrap_disk_free(vfs_handle_struct *handle, const char *path,
                                  uint64_t *bsize, uint64_t *dfree,
                                  uint64_t *dsize)
 {
-       uint64_t result;
+       if (sys_fsusage(path, dfree, dsize) != 0) {
+               return (uint64_t)-1;
+       }
 
-       result = sys_disk_free(handle->conn, path, bsize, dfree, dsize);
-       return result;
+       *bsize = 512;
+       return *dfree / 2;
 }
 
-static int vfswrap_get_quota(struct vfs_handle_struct *handle, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *qt)
+static int vfswrap_get_quota(struct vfs_handle_struct *handle, const char *path,
+                            enum SMB_QUOTA_TYPE qtype, unid_t id,
+                            SMB_DISK_QUOTA *qt)
 {
 #ifdef HAVE_SYS_QUOTAS
        int result;
 
        START_PROFILE(syscall_get_quota);
-       result = sys_get_quota(handle->conn->connectpath, qtype, id, qt);
+       result = sys_get_quota(path, qtype, id, qt);
        END_PROFILE(syscall_get_quota);
        return result;
 #else
@@ -129,7 +134,7 @@ static uint32_t vfswrap_fs_capabilities(struct vfs_handle_struct *handle,
         * use when setting a timestamp. */
 
        smb_fname_cpath = synthetic_smb_fname(talloc_tos(), conn->connectpath,
-                                             NULL, NULL);
+                                             NULL, NULL, 0);
        if (smb_fname_cpath == NULL) {
                return caps;
        }
@@ -371,12 +376,15 @@ static NTSTATUS vfswrap_snap_delete(struct vfs_handle_struct *handle,
 
 /* Directory operations */
 
-static DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32_t attr)
+static DIR *vfswrap_opendir(vfs_handle_struct *handle,
+                               const struct smb_filename *smb_fname,
+                               const char *mask,
+                               uint32_t attr)
 {
        DIR *result;
 
        START_PROFILE(syscall_opendir);
-       result = opendir(fname);
+       result = opendir(smb_fname->base_name);
        END_PROFILE(syscall_opendir);
        return result;
 }
@@ -412,13 +420,20 @@ static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
                if (result != NULL) {
                        /* See if we can efficiently return this. */
                        struct stat st;
-                       int flags = (lp_posix_pathnames() ?
-                               AT_SYMLINK_NOFOLLOW : 0);
+                       int flags = AT_SYMLINK_NOFOLLOW;
                        int ret = fstatat(dirfd(dirp),
                                        result->d_name,
                                        &st,
                                        flags);
-                       if (ret == 0) {
+                       /*
+                        * As this is an optimization,
+                        * ignore it if we stat'ed a
+                        * symlink. Make the caller
+                        * do it again as we don't
+                        * know if they wanted the link
+                        * info, or its target info.
+                        */
+                       if ((ret == 0) && (!S_ISLNK(st.st_mode))) {
                                init_stat_ex_from_stat(sbuf,
                                        &st,
                                        lp_fake_directory_create_times(
@@ -461,18 +476,22 @@ static void vfswrap_rewinddir(vfs_handle_struct *handle, DIR *dirp)
        END_PROFILE(syscall_rewinddir);
 }
 
-static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
+static int vfswrap_mkdir(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       mode_t mode)
 {
        int result;
        bool has_dacl = False;
+       const char *path = smb_fname->base_name;
        char *parent = NULL;
 
        START_PROFILE(syscall_mkdir);
 
        if (lp_inherit_acls(SNUM(handle->conn))
            && parent_dirname(talloc_tos(), path, &parent, NULL)
-           && (has_dacl = directory_has_default_acl(handle->conn, parent)))
+           && (has_dacl = directory_has_default_acl(handle->conn, parent))) {
                mode = (0777 & lp_directory_mask(SNUM(handle->conn)));
+       }
 
        TALLOC_FREE(parent);
 
@@ -487,20 +506,23 @@ static int vfswrap_mkdir(vfs_handle_struct *handle, const char *path, mode_t mod
                 * mess up any inherited ACL bits that were set. JRA.
                 */
                int saved_errno = errno; /* We may get ENOSYS */
-               if ((SMB_VFS_CHMOD_ACL(handle->conn, path, mode) == -1) && (errno == ENOSYS))
+               if ((SMB_VFS_CHMOD_ACL(handle->conn, smb_fname, mode) == -1) &&
+                               (errno == ENOSYS)) {
                        errno = saved_errno;
+               }
        }
 
        END_PROFILE(syscall_mkdir);
        return result;
 }
 
-static int vfswrap_rmdir(vfs_handle_struct *handle, const char *path)
+static int vfswrap_rmdir(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname)
 {
        int result;
 
        START_PROFILE(syscall_rmdir);
-       result = rmdir(path);
+       result = rmdir(smb_fname->base_name);
        END_PROFILE(syscall_rmdir);
        return result;
 }
@@ -684,55 +706,33 @@ static ssize_t vfswrap_pwrite(vfs_handle_struct *handle, files_struct *fsp, cons
        return result;
 }
 
-static void vfswrap_asys_finished(struct tevent_context *ev,
-                                 struct tevent_fd *fde,
-                                 uint16_t flags, void *p);
-
-static bool vfswrap_init_asys_ctx(struct smbd_server_connection *conn)
+static int vfswrap_init_pool(struct smbd_server_connection *conn)
 {
        int ret;
-       int fd;
 
-       if (conn->asys_ctx != NULL) {
-               return true;
-       }
-       ret = asys_context_init(&conn->asys_ctx, aio_pending_size);
-       if (ret != 0) {
-               DEBUG(1, ("asys_context_init failed: %s\n", strerror(ret)));
-               return false;
+       if (conn->pool != NULL) {
+               return 0;
        }
 
-       fd = asys_signalfd(conn->asys_ctx);
-
-       set_blocking(fd, false);
-
-       conn->asys_fde = tevent_add_fd(conn->ev_ctx, conn, fd,
-                                      TEVENT_FD_READ,
-                                      vfswrap_asys_finished,
-                                      conn->asys_ctx);
-       if (conn->asys_fde == NULL) {
-               DEBUG(1, ("tevent_add_fd failed\n"));
-               asys_context_destroy(conn->asys_ctx);
-               conn->asys_ctx = NULL;
-               return false;
-       }
-       return true;
+       ret = pthreadpool_tevent_init(conn, lp_aio_max_threads(),
+                                     &conn->pool);
+       return ret;
 }
 
-struct vfswrap_asys_state {
-       struct asys_context *asys_ctx;
-       struct tevent_req *req;
+struct vfswrap_pread_state {
        ssize_t ret;
        int err;
-       SMBPROFILE_BASIC_ASYNC_STATE(profile_basic);
+       int fd;
+       void *buf;
+       size_t count;
+       off_t offset;
+
+       struct vfs_aio_state vfs_aio_state;
        SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
 };
 
-static int vfswrap_asys_state_destructor(struct vfswrap_asys_state *s)
-{
-       asys_cancel(s->asys_ctx, s->req);
-       return 0;
-}
+static void vfs_pread_do(void *private_data);
+static void vfs_pread_done(struct tevent_req *subreq);
 
 static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
                                             TALLOC_CTX *mem_ctx,
@@ -741,33 +741,115 @@ static struct tevent_req *vfswrap_pread_send(struct vfs_handle_struct *handle,
                                             void *data,
                                             size_t n, off_t offset)
 {
-       struct tevent_req *req;
-       struct vfswrap_asys_state *state;
+       struct tevent_req *req, *subreq;
+       struct vfswrap_pread_state *state;
        int ret;
 
-       req = tevent_req_create(mem_ctx, &state, struct vfswrap_asys_state);
+       req = tevent_req_create(mem_ctx, &state, struct vfswrap_pread_state);
        if (req == NULL) {
                return NULL;
        }
-       if (!vfswrap_init_asys_ctx(handle->conn->sconn)) {
-               tevent_req_oom(req);
+
+       ret = vfswrap_init_pool(handle->conn->sconn);
+       if (tevent_req_error(req, ret)) {
                return tevent_req_post(req, ev);
        }
-       state->asys_ctx = handle->conn->sconn->asys_ctx;
-       state->req = req;
+
+       state->ret = -1;
+       state->fd = fsp->fh->fd;
+       state->buf = data;
+       state->count = n;
+       state->offset = offset;
 
        SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pread, profile_p,
                                     state->profile_bytes, n);
-       ret = asys_pread(state->asys_ctx, fsp->fh->fd, data, n, offset, req);
-       if (ret != 0) {
-               tevent_req_error(req, ret);
+       SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
+
+       subreq = pthreadpool_tevent_job_send(
+               state, ev, handle->conn->sconn->pool,
+               vfs_pread_do, state);
+       if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       talloc_set_destructor(state, vfswrap_asys_state_destructor);
+       tevent_req_set_callback(subreq, vfs_pread_done, req);
 
        return req;
 }
 
+static void vfs_pread_do(void *private_data)
+{
+       struct vfswrap_pread_state *state = talloc_get_type_abort(
+               private_data, struct vfswrap_pread_state);
+       struct timespec start_time;
+       struct timespec end_time;
+
+       SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes);
+
+       PROFILE_TIMESTAMP(&start_time);
+
+       do {
+               state->ret = pread(state->fd, state->buf, state->count,
+                                  state->offset);
+       } while ((state->ret == -1) && (errno == EINTR));
+
+       state->err = errno;
+
+       PROFILE_TIMESTAMP(&end_time);
+
+       state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
+
+       SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
+}
+
+static void vfs_pread_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+#ifdef WITH_PROFILE
+       struct vfswrap_pread_state *state = tevent_req_data(
+               req, struct vfswrap_pread_state);
+#endif
+       int ret;
+
+       ret = pthreadpool_tevent_job_recv(subreq);
+       TALLOC_FREE(subreq);
+       SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
+       if (tevent_req_error(req, ret)) {
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+static ssize_t vfswrap_pread_recv(struct tevent_req *req,
+                                 struct vfs_aio_state *vfs_aio_state)
+{
+       struct vfswrap_pread_state *state = tevent_req_data(
+               req, struct vfswrap_pread_state);
+
+       if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+               return -1;
+       }
+
+       *vfs_aio_state = state->vfs_aio_state;
+       return state->ret;
+}
+
+struct vfswrap_pwrite_state {
+       ssize_t ret;
+       int err;
+       int fd;
+       const void *buf;
+       size_t count;
+       off_t offset;
+
+       struct vfs_aio_state vfs_aio_state;
+       SMBPROFILE_BYTES_ASYNC_STATE(profile_bytes);
+};
+
+static void vfs_pwrite_do(void *private_data);
+static void vfs_pwrite_done(struct tevent_req *subreq);
+
 static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
                                              TALLOC_CTX *mem_ctx,
                                              struct tevent_context *ev,
@@ -775,128 +857,198 @@ static struct tevent_req *vfswrap_pwrite_send(struct vfs_handle_struct *handle,
                                              const void *data,
                                              size_t n, off_t offset)
 {
-       struct tevent_req *req;
-       struct vfswrap_asys_state *state;
+       struct tevent_req *req, *subreq;
+       struct vfswrap_pwrite_state *state;
        int ret;
 
-       req = tevent_req_create(mem_ctx, &state, struct vfswrap_asys_state);
+       req = tevent_req_create(mem_ctx, &state, struct vfswrap_pwrite_state);
        if (req == NULL) {
                return NULL;
        }
-       if (!vfswrap_init_asys_ctx(handle->conn->sconn)) {
-               tevent_req_oom(req);
+
+       ret = vfswrap_init_pool(handle->conn->sconn);
+       if (tevent_req_error(req, ret)) {
                return tevent_req_post(req, ev);
        }
-       state->asys_ctx = handle->conn->sconn->asys_ctx;
-       state->req = req;
+
+       state->ret = -1;
+       state->fd = fsp->fh->fd;
+       state->buf = data;
+       state->count = n;
+       state->offset = offset;
 
        SMBPROFILE_BYTES_ASYNC_START(syscall_asys_pwrite, profile_p,
                                     state->profile_bytes, n);
-       ret = asys_pwrite(state->asys_ctx, fsp->fh->fd, data, n, offset, req);
-       if (ret != 0) {
-               tevent_req_error(req, ret);
+       SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
+
+       subreq = pthreadpool_tevent_job_send(
+               state, ev, handle->conn->sconn->pool,
+               vfs_pwrite_do, state);
+       if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       talloc_set_destructor(state, vfswrap_asys_state_destructor);
+       tevent_req_set_callback(subreq, vfs_pwrite_done, req);
 
        return req;
 }
 
+static void vfs_pwrite_do(void *private_data)
+{
+       struct vfswrap_pwrite_state *state = talloc_get_type_abort(
+               private_data, struct vfswrap_pwrite_state);
+       struct timespec start_time;
+       struct timespec end_time;
+
+       SMBPROFILE_BYTES_ASYNC_SET_BUSY(state->profile_bytes);
+
+       PROFILE_TIMESTAMP(&start_time);
+
+       do {
+               state->ret = pwrite(state->fd, state->buf, state->count,
+                                  state->offset);
+       } while ((state->ret == -1) && (errno == EINTR));
+
+       state->err = errno;
+
+       PROFILE_TIMESTAMP(&end_time);
+
+       state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
+
+       SMBPROFILE_BYTES_ASYNC_SET_IDLE(state->profile_bytes);
+}
+
+static void vfs_pwrite_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+#ifdef WITH_PROFILE
+       struct vfswrap_pwrite_state *state = tevent_req_data(
+               req, struct vfswrap_pwrite_state);
+#endif
+       int ret;
+
+       ret = pthreadpool_tevent_job_recv(subreq);
+       TALLOC_FREE(subreq);
+       SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
+       if (tevent_req_error(req, ret)) {
+               return;
+       }
+
+       tevent_req_done(req);
+}
+
+static ssize_t vfswrap_pwrite_recv(struct tevent_req *req,
+                                  struct vfs_aio_state *vfs_aio_state)
+{
+       struct vfswrap_pwrite_state *state = tevent_req_data(
+               req, struct vfswrap_pwrite_state);
+
+       if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
+               return -1;
+       }
+
+       *vfs_aio_state = state->vfs_aio_state;
+       return state->ret;
+}
+
+struct vfswrap_fsync_state {
+       ssize_t ret;
+       int err;
+       int fd;
+
+       struct vfs_aio_state vfs_aio_state;
+       SMBPROFILE_BASIC_ASYNC_STATE(profile_basic);
+};
+
+static void vfs_fsync_do(void *private_data);
+static void vfs_fsync_done(struct tevent_req *subreq);
+
 static struct tevent_req *vfswrap_fsync_send(struct vfs_handle_struct *handle,
                                             TALLOC_CTX *mem_ctx,
                                             struct tevent_context *ev,
                                             struct files_struct *fsp)
 {
-       struct tevent_req *req;
-       struct vfswrap_asys_state *state;
+       struct tevent_req *req, *subreq;
+       struct vfswrap_fsync_state *state;
        int ret;
 
-       req = tevent_req_create(mem_ctx, &state, struct vfswrap_asys_state);
+       req = tevent_req_create(mem_ctx, &state, struct vfswrap_fsync_state);
        if (req == NULL) {
                return NULL;
        }
-       if (!vfswrap_init_asys_ctx(handle->conn->sconn)) {
-               tevent_req_oom(req);
+
+       ret = vfswrap_init_pool(handle->conn->sconn);
+       if (tevent_req_error(req, ret)) {
                return tevent_req_post(req, ev);
        }
-       state->asys_ctx = handle->conn->sconn->asys_ctx;
-       state->req = req;
+
+       state->ret = -1;
+       state->fd = fsp->fh->fd;
 
        SMBPROFILE_BASIC_ASYNC_START(syscall_asys_fsync, profile_p,
                                     state->profile_basic);
-       ret = asys_fsync(state->asys_ctx, fsp->fh->fd, req);
-       if (ret != 0) {
-               tevent_req_error(req, ret);
+
+       subreq = pthreadpool_tevent_job_send(
+               state, ev, handle->conn->sconn->pool, vfs_fsync_do, state);
+       if (tevent_req_nomem(subreq, req)) {
                return tevent_req_post(req, ev);
        }
-       talloc_set_destructor(state, vfswrap_asys_state_destructor);
+       tevent_req_set_callback(subreq, vfs_fsync_done, req);
 
        return req;
 }
 
-static void vfswrap_asys_finished(struct tevent_context *ev,
-                                       struct tevent_fd *fde,
-                                       uint16_t flags, void *p)
+static void vfs_fsync_do(void *private_data)
 {
-       struct asys_context *asys_ctx = (struct asys_context *)p;
-       struct asys_result results[outstanding_aio_calls];
-       int i, ret;
+       struct vfswrap_fsync_state *state = talloc_get_type_abort(
+               private_data, struct vfswrap_fsync_state);
+       struct timespec start_time;
+       struct timespec end_time;
 
-       if ((flags & TEVENT_FD_READ) == 0) {
-               return;
-       }
-
-       ret = asys_results(asys_ctx, results, outstanding_aio_calls);
-       if (ret < 0) {
-               DEBUG(1, ("asys_results returned %s\n", strerror(-ret)));
-               return;
-       }
-
-       for (i=0; i<ret; i++) {
-               struct asys_result *result = &results[i];
-               struct tevent_req *req;
-               struct vfswrap_asys_state *state;
+       PROFILE_TIMESTAMP(&start_time);
 
-               if ((result->ret == -1) && (result->err == ECANCELED)) {
-                       continue;
-               }
+       do {
+               state->ret = fsync(state->fd);
+       } while ((state->ret == -1) && (errno == EINTR));
 
-               req = talloc_get_type_abort(result->private_data,
-                                           struct tevent_req);
-               state = tevent_req_data(req, struct vfswrap_asys_state);
+       state->err = errno;
 
-               talloc_set_destructor(state, NULL);
+       PROFILE_TIMESTAMP(&end_time);
 
-               SMBPROFILE_BASIC_ASYNC_END(state->profile_basic);
-               SMBPROFILE_BYTES_ASYNC_END(state->profile_bytes);
-               state->ret = result->ret;
-               state->err = result->err;
-               tevent_req_defer_callback(req, ev);
-               tevent_req_done(req);
-       }
+       state->vfs_aio_state.duration = nsec_time_diff(&end_time, &start_time);
 }
 
-static ssize_t vfswrap_asys_ssize_t_recv(struct tevent_req *req, int *err)
+static void vfs_fsync_done(struct tevent_req *subreq)
 {
-       struct vfswrap_asys_state *state = tevent_req_data(
-               req, struct vfswrap_asys_state);
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+#ifdef WITH_PROFILE
+       struct vfswrap_fsync_state *state = tevent_req_data(
+               req, struct vfswrap_fsync_state);
+#endif
+       int ret;
 
-       if (tevent_req_is_unix_error(req, err)) {
-               return -1;
+       ret = pthreadpool_tevent_job_recv(subreq);
+       TALLOC_FREE(subreq);
+       SMBPROFILE_BASIC_ASYNC_END(state->profile_basic);
+       if (tevent_req_error(req, ret)) {
+               return;
        }
-       *err = state->err;
-       return state->ret;
+
+       tevent_req_done(req);
 }
 
-static int vfswrap_asys_int_recv(struct tevent_req *req, int *err)
+static int vfswrap_fsync_recv(struct tevent_req *req,
+                             struct vfs_aio_state *vfs_aio_state)
 {
-       struct vfswrap_asys_state *state = tevent_req_data(
-               req, struct vfswrap_asys_state);
+       struct vfswrap_fsync_state *state = tevent_req_data(
+               req, struct vfswrap_fsync_state);
 
-       if (tevent_req_is_unix_error(req, err)) {
+       if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
                return -1;
        }
-       *err = state->err;
+
+       *vfs_aio_state = state->vfs_aio_state;
        return state->ret;
 }
 
@@ -1270,7 +1422,7 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
                /* unknown 4 bytes: this is not the length of the sid :-(  */
                /*unknown = IVAL(pdata,0);*/
 
-               if (!sid_parse(in_data + 4, sid_len, &sid)) {
+               if (!sid_parse(_in_data + 4, sid_len, &sid)) {
                        return NT_STATUS_INVALID_PARAMETER;
                }
                DEBUGADD(10, ("for SID: %s\n", sid_string_dbg(&sid)));
@@ -1393,11 +1545,70 @@ static NTSTATUS vfswrap_fsctl(struct vfs_handle_struct *handle,
        return NT_STATUS_NOT_SUPPORTED;
 }
 
+static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
+                              const struct smb_filename *fname,
+                              SMB_STRUCT_STAT *sbuf);
+
+static NTSTATUS vfswrap_get_dos_attributes(struct vfs_handle_struct *handle,
+                                          struct smb_filename *smb_fname,
+                                          uint32_t *dosmode)
+{
+       bool offline;
+
+       offline = vfswrap_is_offline(handle, smb_fname, &smb_fname->st);
+       if (offline) {
+               *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+       }
+
+       return get_ea_dos_attribute(handle->conn, smb_fname, dosmode);
+}
+
+static NTSTATUS vfswrap_fget_dos_attributes(struct vfs_handle_struct *handle,
+                                           struct files_struct *fsp,
+                                           uint32_t *dosmode)
+{
+       bool offline;
+
+       offline = vfswrap_is_offline(handle, fsp->fsp_name, &fsp->fsp_name->st);
+       if (offline) {
+               *dosmode |= FILE_ATTRIBUTE_OFFLINE;
+       }
+
+       return get_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
+}
+
+static NTSTATUS vfswrap_set_dos_attributes(struct vfs_handle_struct *handle,
+                                          const struct smb_filename *smb_fname,
+                                          uint32_t dosmode)
+{
+       return set_ea_dos_attribute(handle->conn, smb_fname, dosmode);
+}
+
+static NTSTATUS vfswrap_fset_dos_attributes(struct vfs_handle_struct *handle,
+                                           struct files_struct *fsp,
+                                           uint32_t dosmode)
+{
+       return set_ea_dos_attribute(handle->conn, fsp->fsp_name, dosmode);
+}
+
 struct vfs_cc_state {
-       off_t copied;
-       uint8_t buf[65536];
+       struct tevent_context *ev;
+       uint8_t *buf;
+       bool read_lck_locked;
+       struct lock_struct read_lck;
+       bool write_lck_locked;
+       struct lock_struct write_lck;
+       struct files_struct *src_fsp;
+       off_t src_off;
+       struct files_struct *dst_fsp;
+       off_t dst_off;
+       off_t to_copy;
+       off_t remaining;
+       size_t next_io_size;
 };
 
+static NTSTATUS copy_chunk_loop(struct tevent_req *req);
+
 static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *handle,
                                                  TALLOC_CTX *mem_ctx,
                                                  struct tevent_context *ev,
@@ -1405,20 +1616,34 @@ 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 num)
+                                                 off_t to_copy)
 {
        struct tevent_req *req;
-       struct vfs_cc_state *vfs_cc_state;
+       struct vfs_cc_state *state = NULL;
+       size_t num = MIN(to_copy, COPYCHUNK_MAX_TOTAL_LEN);
        NTSTATUS status;
 
-       DEBUG(10, ("performing server side copy chunk of length %lu\n",
-                  (unsigned long)num));
+       DBG_DEBUG("server side copy chunk of length %" PRIu64 "\n", to_copy);
 
-       req = tevent_req_create(mem_ctx, &vfs_cc_state, struct vfs_cc_state);
+       req = tevent_req_create(mem_ctx, &state, struct vfs_cc_state);
        if (req == NULL) {
                return NULL;
        }
 
+       *state = (struct vfs_cc_state) {
+               .ev = ev,
+               .src_fsp = src_fsp,
+               .src_off = src_off,
+               .dst_fsp = dest_fsp,
+               .dst_off = dest_off,
+               .to_copy = to_copy,
+               .remaining = to_copy,
+       };
+       state->buf = talloc_array(state, uint8_t, num);
+       if (tevent_req_nomem(state->buf, req)) {
+               return tevent_req_post(req, ev);
+       }
+
        status = vfs_stat_fsp(src_fsp);
        if (tevent_req_nterror(req, status)) {
                return tevent_req_post(req, ev);
@@ -1438,115 +1663,188 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand
                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;
-               struct lock_struct lck;
-               int saved_errno;
+       if (src_fsp->op == NULL) {
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return tevent_req_post(req, ev);
+       }
+
+       if (dest_fsp->op == NULL) {
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return tevent_req_post(req, ev);
+       }
 
-               off_t this_num = MIN(sizeof(vfs_cc_state->buf),
-                                    num - vfs_cc_state->copied);
+       status = copy_chunk_loop(req);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return tevent_req_post(req, ev);
+       }
 
-               if (src_fsp->op == NULL) {
-                       tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-                       return tevent_req_post(req, ev);
-               }
-               init_strict_lock_struct(src_fsp,
-                                       src_fsp->op->global->open_persistent_id,
-                                       src_off,
-                                       this_num,
-                                       READ_LOCK,
-                                       &lck);
-
-               if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &lck)) {
-                       tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-                       return tevent_req_post(req, ev);
-               }
+       return req;
+}
 
-               ret = SMB_VFS_PREAD(src_fsp, vfs_cc_state->buf,
-                                   this_num, src_off);
-               if (ret == -1) {
-                       saved_errno = errno;
-               }
+static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq);
 
-               SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck);
+static NTSTATUS copy_chunk_loop(struct tevent_req *req)
+{
+       struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+       struct tevent_req *subreq = NULL;
+       bool ok;
 
-               if (ret == -1) {
-                       errno = saved_errno;
-                       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);
-               }
+       state->next_io_size = MIN(state->remaining, talloc_array_length(state->buf));
 
-               src_off += ret;
+       init_strict_lock_struct(state->src_fsp,
+                               state->src_fsp->op->global->open_persistent_id,
+                               state->src_off,
+                               state->next_io_size,
+                               READ_LOCK,
+                               &state->read_lck);
 
-               if (dest_fsp->op == NULL) {
-                       tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
-                       return tevent_req_post(req, ev);
-               }
+       ok = SMB_VFS_STRICT_LOCK(state->src_fsp->conn,
+                                state->src_fsp,
+                                &state->read_lck);
+       if (!ok) {
+               return NT_STATUS_FILE_LOCK_CONFLICT;
+       }
 
-               init_strict_lock_struct(dest_fsp,
-                                       dest_fsp->op->global->open_persistent_id,
-                                       dest_off,
-                                       this_num,
-                                       WRITE_LOCK,
-                                       &lck);
+       subreq = SMB_VFS_PREAD_SEND(state,
+                                   state->src_fsp->conn->sconn->ev_ctx,
+                                   state->src_fsp,
+                                   state->buf,
+                                   state->next_io_size,
+                                   state->src_off);
+       if (subreq == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       tevent_req_set_callback(subreq, vfswrap_copy_chunk_read_done, req);
 
-               if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &lck)) {
-                       tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
-                       return tevent_req_post(req, ev);
-               }
+       return NT_STATUS_OK;
+}
 
-               ret = SMB_VFS_PWRITE(dest_fsp, vfs_cc_state->buf,
-                                    this_num, dest_off);
-               if (ret == -1) {
-                       saved_errno = errno;
-               }
+static void vfswrap_copy_chunk_write_done(struct tevent_req *subreq);
 
-               SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck);
+static void vfswrap_copy_chunk_read_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+       struct vfs_aio_state aio_state;
+       ssize_t nread;
+       bool ok;
 
-               if (ret == -1) {
-                       errno = saved_errno;
-                       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;
+       SMB_VFS_STRICT_UNLOCK(state->src_fsp->conn,
+                             state->src_fsp,
+                             &state->read_lck);
+       ZERO_STRUCT(state->read_lck);
 
-               vfs_cc_state->copied += this_num;
+       nread = SMB_VFS_PREAD_RECV(subreq, &aio_state);
+       TALLOC_FREE(subreq);
+       if (nread == -1) {
+               DBG_ERR("read failed: %s\n", strerror(errno));
+               tevent_req_nterror(req, map_nt_error_from_unix(aio_state.error));
+               return;
+       }
+       if (nread != state->next_io_size) {
+               DBG_ERR("Short read, only %zd of %zu\n",
+                       nread, state->next_io_size);
+               tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
+               return;
        }
 
-       tevent_req_done(req);
-       return tevent_req_post(req, ev);
+       state->src_off += nread;
+
+       init_strict_lock_struct(state->dst_fsp,
+                               state->dst_fsp->op->global->open_persistent_id,
+                               state->dst_off,
+                               state->next_io_size,
+                               WRITE_LOCK,
+                               &state->write_lck);
+
+       ok = SMB_VFS_STRICT_LOCK(state->dst_fsp->conn,
+                                state->dst_fsp,
+                                &state->write_lck);
+       if (!ok) {
+               tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT);
+               return;
+       }
+
+       subreq = SMB_VFS_PWRITE_SEND(state,
+                                    state->ev,
+                                    state->dst_fsp,
+                                    state->buf,
+                                    state->next_io_size,
+                                    state->dst_off);
+       if (subreq == NULL) {
+               tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
+               return;
+       }
+       tevent_req_set_callback(subreq, vfswrap_copy_chunk_write_done, req);
+}
+
+static void vfswrap_copy_chunk_write_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct vfs_cc_state *state = tevent_req_data(req, struct vfs_cc_state);
+       struct vfs_aio_state aio_state;
+       ssize_t nwritten;
+       NTSTATUS status;
+
+       SMB_VFS_STRICT_UNLOCK(state->dst_fsp->conn,
+                             state->dst_fsp,
+                             &state->write_lck);
+       ZERO_STRUCT(state->write_lck);
+
+       nwritten = SMB_VFS_PWRITE_RECV(subreq, &aio_state);
+       TALLOC_FREE(subreq);
+       if (nwritten == -1) {
+               DBG_ERR("write failed: %s\n", strerror(errno));
+               tevent_req_nterror(req, map_nt_error_from_unix(aio_state.error));
+               return;
+       }
+       if (nwritten != state->next_io_size) {
+               DBG_ERR("Short write, only %zd of %zu\n", nwritten, state->next_io_size);
+               tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR);
+               return;
+       }
+
+       state->dst_off += nwritten;
+
+       if (state->remaining < nwritten) {
+               /* Paranoia check */
+               tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+               return;
+       }
+       state->remaining -= nwritten;
+       if (state->remaining == 0) {
+               tevent_req_done(req);
+               return;
+       }
+
+       status = copy_chunk_loop(req);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+
+       return;
 }
 
 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);
+       struct vfs_cc_state *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)));
+               DBG_DEBUG("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));
+       *copied = state->to_copy;
+       DBG_DEBUG("copy chunk copied %lu\n", (unsigned long)*copied);
        tevent_req_received(req);
 
        return NT_STATUS_OK;
@@ -1645,7 +1943,9 @@ static int vfswrap_unlink(vfs_handle_struct *handle,
        return result;
 }
 
-static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
+static int vfswrap_chmod(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       mode_t mode)
 {
        int result;
 
@@ -1660,7 +1960,10 @@ static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mod
 
        {
                int saved_errno = errno; /* We might get ENOSYS */
-               if ((result = SMB_VFS_CHMOD_ACL(handle->conn, path, mode)) == 0) {
+               result = SMB_VFS_CHMOD_ACL(handle->conn,
+                               smb_fname,
+                               mode);
+               if (result == 0) {
                        END_PROFILE(syscall_chmod);
                        return result;
                }
@@ -1668,7 +1971,7 @@ static int vfswrap_chmod(vfs_handle_struct *handle, const char *path, mode_t mod
                errno = saved_errno;
        }
 
-       result = chmod(path, mode);
+       result = chmod(smb_fname->base_name, mode);
        END_PROFILE(syscall_chmod);
        return result;
 }
@@ -1706,12 +2009,15 @@ static int vfswrap_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t m
        return result;
 }
 
-static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int vfswrap_chown(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       uid_t uid,
+                       gid_t gid)
 {
        int result;
 
        START_PROFILE(syscall_chown);
-       result = chown(path, uid, gid);
+       result = chown(smb_fname->base_name, uid, gid);
        END_PROFILE(syscall_chown);
        return result;
 }
@@ -1731,12 +2037,15 @@ static int vfswrap_fchown(vfs_handle_struct *handle, files_struct *fsp, uid_t ui
 #endif
 }
 
-static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid, gid_t gid)
+static int vfswrap_lchown(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname,
+                       uid_t uid,
+                       gid_t gid)
 {
        int result;
 
        START_PROFILE(syscall_lchown);
-       result = lchown(path, uid, gid);
+       result = lchown(smb_fname->base_name, uid, gid);
        END_PROFILE(syscall_lchown);
        return result;
 }
@@ -1899,9 +2208,8 @@ static int strict_allocate_ftruncate(vfs_handle_struct *handle, files_struct *fs
                "error %d. Falling back to slow manual allocation\n", errno));
 
        /* available disk space is enough or not? */
-       space_avail = get_dfree_info(fsp->conn,
-                                    fsp->fsp_name->base_name,
-                                    &bsize, &dfree, &dsize);
+       space_avail =
+           get_dfree_info(fsp->conn, fsp->fsp_name, &bsize, &dfree, &dsize);
        /* space_avail is 1k blocks */
        if (space_avail == (uint64_t)-1 ||
                        ((uint64_t)space_to_write/1024 > space_avail) ) {
@@ -2023,6 +2331,14 @@ static bool vfswrap_lock(vfs_handle_struct *handle, files_struct *fsp, int op, o
        bool result;
 
        START_PROFILE(syscall_fcntl_lock);
+
+       if (fsp->use_ofd_locks || !lp_parm_bool(SNUM(fsp->conn),
+                                               "smbd",
+                                               "force process locks",
+                                               false)) {
+               op = map_process_lock_to_ofd_lock(op, &fsp->use_ofd_locks);
+       }
+
        result =  fcntl_lock(fsp->fh->fd, op, offset, count, type);
        END_PROFILE(syscall_fcntl_lock);
        return result;
@@ -2040,9 +2356,18 @@ static int vfswrap_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
 static bool vfswrap_getlock(vfs_handle_struct *handle, files_struct *fsp, off_t *poffset, off_t *pcount, int *ptype, pid_t *ppid)
 {
        bool result;
+       int op = F_GETLK;
 
        START_PROFILE(syscall_fcntl_getlock);
-       result =  fcntl_getlock(fsp->fh->fd, poffset, pcount, ptype, ppid);
+
+       if (fsp->use_ofd_locks || !lp_parm_bool(SNUM(fsp->conn),
+                                               "smbd",
+                                               "force process locks",
+                                               false)) {
+               op = map_process_lock_to_ofd_lock(op, &fsp->use_ofd_locks);
+       }
+
+       result = fcntl_getlock(fsp->fh->fd, op, poffset, pcount, ptype, ppid);
        END_PROFILE(syscall_fcntl_getlock);
        return result;
 }
@@ -2108,69 +2433,11 @@ static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path)
        char *result;
 
        START_PROFILE(syscall_realpath);
-#ifdef REALPATH_TAKES_NULL
-       result = realpath(path, NULL);
-#else
-       result = SMB_MALLOC_ARRAY(char, PATH_MAX+1);
-       if (result) {
-               char *resolved_path = realpath(path, result);
-               if (!resolved_path) {
-                       SAFE_FREE(result);
-               } else {
-                       /* SMB_ASSERT(result == resolved_path) ? */
-                       result = resolved_path;
-               }
-       }
-#endif
+       result = sys_realpath(path);
        END_PROFILE(syscall_realpath);
        return result;
 }
 
-static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
-                                    struct sys_notify_context *ctx,
-                                    const char *path,
-                                    uint32_t *filter,
-                                    uint32_t *subdir_filter,
-                                    void (*callback)(struct sys_notify_context *ctx, 
-                                                     void *private_data,
-                                                     struct notify_event *ev),
-                                    void *private_data, void *handle)
-{
-       /*
-        * So far inotify is the only supported default notify mechanism. If
-        * another platform like the the BSD's or a proprietary Unix comes
-        * along and wants another default, we can play the same trick we
-        * played with Posix ACLs.
-        *
-        * Until that is the case, hard-code inotify here.
-        */
-#ifdef HAVE_INOTIFY
-       if (lp_kernel_change_notify(vfs_handle->conn->params)) {
-               int ret;
-               if (!lp_parm_bool(-1, "notify", "inotify", True)) {
-                       return NT_STATUS_INVALID_SYSTEM_SERVICE;
-               }
-               /*
-                * "ctx->private_data" is not obvious as a talloc context
-                * here. Without modifying the VFS we don't have a mem_ctx
-                * available here, and ctx->private_data was used by
-                * inotify_watch before it got a real talloc parent.
-                */
-               ret = inotify_watch(ctx->private_data, ctx,
-                                   path, filter, subdir_filter,
-                                   callback, private_data, handle);
-               if (ret != 0) {
-                       return map_nt_error_from_unix(ret);
-               }
-               return NT_STATUS_OK;
-       }
-#endif
-       /*
-        * Do nothing, leave everything to notify_internal.c
-        */
-       return NT_STATUS_OK;
-}
-
 static int vfswrap_chflags(vfs_handle_struct *handle, const char *path,
                           unsigned int flags)
 {
@@ -2200,7 +2467,7 @@ static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
 
 static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
                                   struct files_struct *fsp,
-                                  const char *fname,
+                                  const struct smb_filename *smb_fname,
                                   TALLOC_CTX *mem_ctx,
                                   unsigned int *pnum_streams,
                                   struct stream_struct **pstreams)
@@ -2220,17 +2487,19 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct *handle,
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        }
        else {
-               struct smb_filename smb_fname;
+               struct smb_filename smb_fname_cp;
 
-               ZERO_STRUCT(smb_fname);
-               smb_fname.base_name = discard_const_p(char, fname);
+               ZERO_STRUCT(smb_fname_cp);
+               smb_fname_cp.base_name = discard_const_p(char,
+                                       smb_fname->base_name);
+               smb_fname_cp.flags = smb_fname->flags;
 
-               if (lp_posix_pathnames()) {
-                       ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
+               if (smb_fname_cp.flags & SMB_FILENAME_POSIX_PATH) {
+                       ret = SMB_VFS_LSTAT(handle->conn, &smb_fname_cp);
                } else {
-                       ret = SMB_VFS_STAT(handle->conn, &smb_fname);
+                       ret = SMB_VFS_STAT(handle->conn, &smb_fname_cp);
                }
-               sbuf = smb_fname.st;
+               sbuf = smb_fname_cp.st;
        }
 
        if (ret == -1) {
@@ -2348,7 +2617,7 @@ static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle,
 }
 
 static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
-                                  const char *name,
+                                  const struct smb_filename *smb_fname,
                                   uint32_t security_info,
                                   TALLOC_CTX *mem_ctx,
                                   struct security_descriptor **ppdesc)
@@ -2356,8 +2625,11 @@ static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle,
        NTSTATUS result;
 
        START_PROFILE(get_nt_acl);
-       result = posix_get_nt_acl(handle->conn, name, security_info,
-                                 mem_ctx, ppdesc);
+       result = posix_get_nt_acl(handle->conn,
+                               smb_fname,
+                               security_info,
+                               mem_ctx,
+                               ppdesc);
        END_PROFILE(get_nt_acl);
        return result;
 }
@@ -2381,7 +2653,9 @@ static NTSTATUS vfswrap_audit_file(struct vfs_handle_struct *handle,
        return NT_STATUS_OK; /* Nothing to do here ... */
 }
 
-static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode)
+static int vfswrap_chmod_acl(vfs_handle_struct *handle,
+                               const struct smb_filename *smb_fname,
+                               mode_t mode)
 {
 #ifdef HAVE_NO_ACL
        errno = ENOSYS;
@@ -2390,7 +2664,7 @@ static int vfswrap_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t
        int result;
 
        START_PROFILE(chmod_acl);
-       result = chmod_acl(handle->conn, name, mode);
+       result = chmod_acl(handle->conn, smb_fname->base_name, mode);
        END_PROFILE(chmod_acl);
        return result;
 #endif
@@ -2522,16 +2796,6 @@ static bool vfswrap_is_offline(struct vfs_handle_struct *handle,
        return offline;
 }
 
-static int vfswrap_set_offline(struct vfs_handle_struct *handle,
-                              const struct smb_filename *fname)
-{
-       /* We don't know how to set offline bit by default, needs to be overriden in the vfs modules */
-#if defined(ENOTSUP)
-       errno = ENOTSUP;
-#endif
-       return -1;
-}
-
 static NTSTATUS vfswrap_durable_cookie(struct vfs_handle_struct *handle,
                                       struct files_struct *fsp,
                                       TALLOC_CTX *mem_ctx,
@@ -2601,18 +2865,18 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .read_fn = vfswrap_read,
        .pread_fn = vfswrap_pread,
        .pread_send_fn = vfswrap_pread_send,
-       .pread_recv_fn = vfswrap_asys_ssize_t_recv,
+       .pread_recv_fn = vfswrap_pread_recv,
        .write_fn = vfswrap_write,
        .pwrite_fn = vfswrap_pwrite,
        .pwrite_send_fn = vfswrap_pwrite_send,
-       .pwrite_recv_fn = vfswrap_asys_ssize_t_recv,
+       .pwrite_recv_fn = vfswrap_pwrite_recv,
        .lseek_fn = vfswrap_lseek,
        .sendfile_fn = vfswrap_sendfile,
        .recvfile_fn = vfswrap_recvfile,
        .rename_fn = vfswrap_rename,
        .fsync_fn = vfswrap_fsync,
        .fsync_send_fn = vfswrap_fsync_send,
-       .fsync_recv_fn = vfswrap_asys_int_recv,
+       .fsync_recv_fn = vfswrap_fsync_recv,
        .stat_fn = vfswrap_stat,
        .fstat_fn = vfswrap_fstat,
        .lstat_fn = vfswrap_lstat,
@@ -2637,7 +2901,6 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .link_fn = vfswrap_link,
        .mknod_fn = vfswrap_mknod,
        .realpath_fn = vfswrap_realpath,
-       .notify_watch_fn = vfswrap_notify_watch,
        .chflags_fn = vfswrap_chflags,
        .file_id_create_fn = vfswrap_file_id_create,
        .streaminfo_fn = vfswrap_streaminfo,
@@ -2650,6 +2913,10 @@ static struct vfs_fn_pointers vfs_default_fns = {
        .strict_unlock_fn = vfswrap_strict_unlock,
        .translate_name_fn = vfswrap_translate_name,
        .fsctl_fn = vfswrap_fsctl,
+       .set_dos_attributes_fn = vfswrap_set_dos_attributes,
+       .fset_dos_attributes_fn = vfswrap_fset_dos_attributes,
+       .get_dos_attributes_fn = vfswrap_get_dos_attributes,
+       .fget_dos_attributes_fn = vfswrap_fget_dos_attributes,
        .copy_chunk_send_fn = vfswrap_copy_chunk_send,
        .copy_chunk_recv_fn = vfswrap_copy_chunk_recv,
        .get_compression_fn = vfswrap_get_compression,
@@ -2688,18 +2955,14 @@ static struct vfs_fn_pointers vfs_default_fns = {
        /* aio operations */
        .aio_force_fn = vfswrap_aio_force,
 
-       /* offline operations */
-       .is_offline_fn = vfswrap_is_offline,
-       .set_offline_fn = vfswrap_set_offline,
-
        /* durable handle operations */
        .durable_cookie_fn = vfswrap_durable_cookie,
        .durable_disconnect_fn = vfswrap_durable_disconnect,
        .durable_reconnect_fn = vfswrap_durable_reconnect,
 };
 
-NTSTATUS vfs_default_init(void);
-NTSTATUS vfs_default_init(void)
+NTSTATUS vfs_default_init(TALLOC_CTX *);
+NTSTATUS vfs_default_init(TALLOC_CTX *ctx)
 {
        return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
                                DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);