ctdb-scripts: Do not de-duplicate the interfaces list
[samba.git] / source3 / modules / vfs_time_audit.c
index f07bd29f5e349ffb117320c871db3be594089d16..59bc68861b46645cc173d06a10970670c6193456 100644 (file)
@@ -86,6 +86,23 @@ static void smb_time_audit_log_fsp(const char *syscallname, double elapsed,
        TALLOC_FREE(msg);
 }
 
+static void smb_time_audit_log_at(const char *syscallname,
+                                 double elapsed,
+                                 const struct files_struct *dir_fsp,
+                                 const struct smb_filename *smb_fname)
+{
+       char *msg = NULL;
+
+       msg = talloc_asprintf(talloc_tos(),
+                             "filename = \"%s/%s/%s\"",
+                             dir_fsp->conn->connectpath,
+                             dir_fsp->fsp_name->base_name,
+                             smb_fname->base_name);
+
+       smb_time_audit_log_msg(syscallname, elapsed, msg);
+       TALLOC_FREE(msg);
+}
+
 static void smb_time_audit_log_fname(const char *syscallname, double elapsed,
                                    const char *fname)
 {
@@ -247,7 +264,7 @@ static int smb_time_audit_get_shadow_copy_data(struct vfs_handle_struct *handle,
 }
 
 static int smb_time_audit_statvfs(struct vfs_handle_struct *handle,
-                                 const char *path,
+                                 const struct smb_filename *smb_fname,
                                  struct vfs_statvfs_struct *statbuf)
 {
        int result;
@@ -255,12 +272,13 @@ static int smb_time_audit_statvfs(struct vfs_handle_struct *handle,
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_STATVFS(handle, path, statbuf);
+       result = SMB_VFS_NEXT_STATVFS(handle, smb_fname, statbuf);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("statvfs", timediff, path);
+               smb_time_audit_log_fname("statvfs", timediff,
+                       smb_fname->base_name);
        }
 
        return result;
@@ -299,9 +317,84 @@ static NTSTATUS smb_time_audit_get_dfs_referrals(
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log("get_dfs_referrals(", timediff);
+               smb_time_audit_log("get_dfs_referrals", timediff);
+       }
+
+       return result;
+}
+
+static NTSTATUS smb_time_audit_create_dfs_pathat(struct vfs_handle_struct *handle,
+                       struct files_struct *dirfsp,
+                       const struct smb_filename *smb_fname,
+                       const struct referral *reflist,
+                       size_t referral_count)
+{
+       NTSTATUS result;
+       struct timespec ts1,ts2;
+       double timediff;
+       struct smb_filename *full_fname = NULL;
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       clock_gettime_mono(&ts1);
+       result = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
+                       dirfsp,
+                       smb_fname,
+                       reflist,
+                       referral_count);
+       clock_gettime_mono(&ts2);
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log_smb_fname("create_dfs_pathat",
+                       timediff,
+                       full_fname);
+       }
+       TALLOC_FREE(full_fname);
+       return result;
+}
+
+static NTSTATUS smb_time_audit_read_dfs_pathat(struct vfs_handle_struct *handle,
+                       TALLOC_CTX *mem_ctx,
+                       struct files_struct *dirfsp,
+                       struct smb_filename *smb_fname,
+                       struct referral **ppreflist,
+                       size_t *preferral_count)
+{
+       NTSTATUS result;
+       struct timespec ts1,ts2;
+       double timediff;
+       struct smb_filename *full_fname = NULL;
+
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       clock_gettime_mono(&ts1);
+       result = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
+                       mem_ctx,
+                       dirfsp,
+                       smb_fname,
+                       ppreflist,
+                       preferral_count);
+       clock_gettime_mono(&ts2);
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+
+       if (timediff > audit_timeout) {
+               smb_time_audit_log_smb_fname("read_dfs_pathat",
+                       timediff,
+                       full_fname);
        }
 
+       TALLOC_FREE(full_fname);
        return result;
 }
 
@@ -374,26 +467,6 @@ static NTSTATUS smb_time_audit_snap_delete(struct vfs_handle_struct *handle,
        return status;
 }
 
-static DIR *smb_time_audit_opendir(vfs_handle_struct *handle,
-                                  const struct smb_filename *smb_fname,
-                                  const char *mask, uint32_t attr)
-{
-       DIR *result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_OPENDIR(handle, smb_fname, mask, attr);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("opendir", timediff, smb_fname);
-       }
-
-       return result;
-}
-
 static DIR *smb_time_audit_fdopendir(vfs_handle_struct *handle,
                                              files_struct *fsp,
                                              const char *mask, uint32_t attr)
@@ -415,15 +488,15 @@ static DIR *smb_time_audit_fdopendir(vfs_handle_struct *handle,
 }
 
 static struct dirent *smb_time_audit_readdir(vfs_handle_struct *handle,
-                                                DIR *dirp,
-                                                SMB_STRUCT_STAT *sbuf)
+                                            struct files_struct *dirfsp,
+                                            DIR *dirp)
 {
        struct dirent *result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_READDIR(handle, dirp, sbuf);
+       result = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
@@ -434,42 +507,6 @@ static struct dirent *smb_time_audit_readdir(vfs_handle_struct *handle,
        return result;
 }
 
-static void smb_time_audit_seekdir(vfs_handle_struct *handle,
-                                  DIR *dirp, long offset)
-{
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log("seekdir", timediff);
-       }
-
-}
-
-static long smb_time_audit_telldir(vfs_handle_struct *handle,
-                                  DIR *dirp)
-{
-       long result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_TELLDIR(handle, dirp);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log("telldir", timediff);
-       }
-
-       return result;
-}
-
 static void smb_time_audit_rewinddir(vfs_handle_struct *handle,
                                     DIR *dirp)
 {
@@ -487,46 +524,40 @@ static void smb_time_audit_rewinddir(vfs_handle_struct *handle,
 
 }
 
-static int smb_time_audit_mkdir(vfs_handle_struct *handle,
+static int smb_time_audit_mkdirat(vfs_handle_struct *handle,
+                               struct files_struct *dirfsp,
                                const struct smb_filename *smb_fname,
                                mode_t mode)
 {
+       struct smb_filename *full_fname = NULL;
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_MKDIR(handle, smb_fname, mode);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("mkdir",
-                       timediff,
-                       smb_fname);
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
        }
 
-       return result;
-}
-
-static int smb_time_audit_rmdir(vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_RMDIR(handle, smb_fname);
+       result = SMB_VFS_NEXT_MKDIRAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               mode);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("rmdir",
+               smb_time_audit_log_smb_fname("mkdirat",
                        timediff,
-                       smb_fname);
+                       full_fname);
        }
 
+       TALLOC_FREE(full_fname);
+
        return result;
 }
 
@@ -549,38 +580,27 @@ static int smb_time_audit_closedir(vfs_handle_struct *handle,
        return result;
 }
 
-static void smb_time_audit_init_search_op(vfs_handle_struct *handle,
-                                         DIR *dirp)
-{
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       SMB_VFS_NEXT_INIT_SEARCH_OP(handle, dirp);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log("init_search_op", timediff);
-       }
-}
-
-static int smb_time_audit_open(vfs_handle_struct *handle,
-                              struct smb_filename *fname,
-                              files_struct *fsp,
-                              int flags, mode_t mode)
+static int smb_time_audit_openat(vfs_handle_struct *handle,
+                                const struct files_struct *dirfsp,
+                                const struct smb_filename *smb_fname,
+                                struct files_struct *fsp,
+                                const struct vfs_open_how *how)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode);
+       result = SMB_VFS_NEXT_OPENAT(handle,
+                                    dirfsp,
+                                    smb_fname,
+                                    fsp,
+                                    how);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("open", timediff, fsp);
+               smb_time_audit_log_fsp("openat", timediff, fsp);
        }
 
        return result;
@@ -588,7 +608,7 @@ static int smb_time_audit_open(vfs_handle_struct *handle,
 
 static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle,
                                           struct smb_request *req,
-                                          uint16_t root_dir_fid,
+                                          struct files_struct *dirfsp,
                                           struct smb_filename *fname,
                                           uint32_t access_mask,
                                           uint32_t share_access,
@@ -596,7 +616,7 @@ static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle,
                                           uint32_t create_options,
                                           uint32_t file_attributes,
                                           uint32_t oplock_request,
-                                          struct smb2_lease *lease,
+                                          const struct smb2_lease *lease,
                                           uint64_t allocation_size,
                                           uint32_t private_flags,
                                           struct security_descriptor *sd,
@@ -614,7 +634,7 @@ static NTSTATUS smb_time_audit_create_file(vfs_handle_struct *handle,
        result = SMB_VFS_NEXT_CREATE_FILE(
                handle,                                 /* handle */
                req,                                    /* req */
-               root_dir_fid,                           /* root_dir_fid */
+               dirfsp,                                 /* dirfsp */
                fname,                                  /* fname */
                access_mask,                            /* access_mask */
                share_access,                           /* share_access */
@@ -663,25 +683,6 @@ static int smb_time_audit_close(vfs_handle_struct *handle, files_struct *fsp)
        return result;
 }
 
-static ssize_t smb_time_audit_read(vfs_handle_struct *handle,
-                                  files_struct *fsp, void *data, size_t n)
-{
-       ssize_t result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_READ(handle, fsp, data, n);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("read", timediff, fsp);
-       }
-
-       return result;
-}
-
 static ssize_t smb_time_audit_pread(vfs_handle_struct *handle,
                                    files_struct *fsp,
                                    void *data, size_t n, off_t offset)
@@ -766,26 +767,6 @@ static ssize_t smb_time_audit_pread_recv(struct tevent_req *req,
        return state->ret;
 }
 
-static ssize_t smb_time_audit_write(vfs_handle_struct *handle,
-                                   files_struct *fsp,
-                                   const void *data, size_t n)
-{
-       ssize_t result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_WRITE(handle, fsp, data, n);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("write", timediff, fsp);
-       }
-
-       return result;
-}
-
 static ssize_t smb_time_audit_pwrite(vfs_handle_struct *handle,
                                     files_struct *fsp,
                                     const void *data, size_t n,
@@ -933,41 +914,40 @@ static ssize_t smb_time_audit_recvfile(vfs_handle_struct *handle, int fromfd,
        return result;
 }
 
-static int smb_time_audit_rename(vfs_handle_struct *handle,
-                                const struct smb_filename *oldname,
-                                const struct smb_filename *newname)
+static int smb_time_audit_renameat(vfs_handle_struct *handle,
+                               files_struct *srcfsp,
+                               const struct smb_filename *oldname,
+                               files_struct *dstfsp,
+                               const struct smb_filename *newname)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
+       struct smb_filename *new_full_fname = NULL;
 
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_RENAME(handle, oldname, newname);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("rename", timediff, newname);
+       new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dstfsp,
+                                                 newname);
+       if (new_full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
        }
-
-       return result;
-}
-
-static int smb_time_audit_fsync(vfs_handle_struct *handle, files_struct *fsp)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_FSYNC(handle, fsp);
+       result = SMB_VFS_NEXT_RENAMEAT(handle,
+                       srcfsp,
+                       oldname,
+                       dstfsp,
+                       newname);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("fsync", timediff, fsp);
+               smb_time_audit_log_smb_fname("renameat",
+                                       timediff,
+                                       new_full_fname);
        }
 
+       TALLOC_FREE(new_full_fname);
        return result;
 }
 
@@ -1090,64 +1070,79 @@ static int smb_time_audit_lstat(vfs_handle_struct *handle,
        return result;
 }
 
-static uint64_t smb_time_audit_get_alloc_size(vfs_handle_struct *handle,
-                                             files_struct *fsp,
-                                             const SMB_STRUCT_STAT *sbuf)
+static int smb_time_audit_fstatat(
+       struct vfs_handle_struct *handle,
+       const struct files_struct *dirfsp,
+       const struct smb_filename *smb_fname,
+       SMB_STRUCT_STAT *sbuf,
+       int flags)
 {
-       uint64_t result;
+       int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GET_ALLOC_SIZE(handle, fsp, sbuf);
+       result = SMB_VFS_NEXT_FSTATAT(handle, dirfsp, smb_fname, sbuf, flags);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("get_alloc_size", timediff, fsp);
+               smb_time_audit_log_smb_fname("fstatat", timediff, smb_fname);
        }
 
        return result;
 }
 
-static int smb_time_audit_unlink(vfs_handle_struct *handle,
-                                const struct smb_filename *path)
+static uint64_t smb_time_audit_get_alloc_size(vfs_handle_struct *handle,
+                                             files_struct *fsp,
+                                             const SMB_STRUCT_STAT *sbuf)
 {
-       int result;
+       uint64_t result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_UNLINK(handle, path);
+       result = SMB_VFS_NEXT_GET_ALLOC_SIZE(handle, fsp, sbuf);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("unlink", timediff, path);
+               smb_time_audit_log_fsp("get_alloc_size", timediff, fsp);
        }
 
        return result;
 }
 
-static int smb_time_audit_chmod(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname,
-                       mode_t mode)
+static int smb_time_audit_unlinkat(vfs_handle_struct *handle,
+                       struct files_struct *dirfsp,
+                       const struct smb_filename *path,
+                       int flags)
 {
+       struct smb_filename *full_fname = NULL;
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 path);
+       if (full_fname == NULL) {
+               return -1;
+       }
+
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
+       result = SMB_VFS_NEXT_UNLINKAT(handle,
+                               dirfsp,
+                               path,
+                               flags);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("chmod",
-                       timediff,
-                       smb_fname->base_name);
+               smb_time_audit_log_smb_fname("unlinkat", timediff, full_fname);
        }
 
+       TALLOC_FREE(full_fname);
        return result;
 }
 
@@ -1170,29 +1165,6 @@ static int smb_time_audit_fchmod(vfs_handle_struct *handle, files_struct *fsp,
        return result;
 }
 
-static int smb_time_audit_chown(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname,
-                       uid_t uid,
-                       gid_t gid)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_CHOWN(handle, smb_fname, uid, gid);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("chown",
-                       timediff,
-                       smb_fname->base_name);
-       }
-
-       return result;
-}
-
 static int smb_time_audit_fchown(vfs_handle_struct *handle, files_struct *fsp,
                                 uid_t uid, gid_t gid)
 {
@@ -1235,32 +1207,36 @@ static int smb_time_audit_lchown(vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_time_audit_chdir(vfs_handle_struct *handle, const char *path)
+static int smb_time_audit_chdir(vfs_handle_struct *handle,
+                       const struct smb_filename *smb_fname)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_CHDIR(handle, path);
+       result = SMB_VFS_NEXT_CHDIR(handle, smb_fname);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("chdir", timediff, path);
+               smb_time_audit_log_fname("chdir",
+                       timediff,
+                       smb_fname->base_name);
        }
 
        return result;
 }
 
-static char *smb_time_audit_getwd(vfs_handle_struct *handle)
+static struct smb_filename *smb_time_audit_getwd(vfs_handle_struct *handle,
+                                       TALLOC_CTX *mem_ctx)
 {
-       char *result;
+       struct smb_filename *result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GETWD(handle);
+       result = SMB_VFS_NEXT_GETWD(handle, mem_ctx);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
@@ -1271,21 +1247,21 @@ static char *smb_time_audit_getwd(vfs_handle_struct *handle)
        return result;
 }
 
-static int smb_time_audit_ntimes(vfs_handle_struct *handle,
-                                const struct smb_filename *path,
-                                struct smb_file_time *ft)
+static int smb_time_audit_fntimes(vfs_handle_struct *handle,
+                                 files_struct *fsp,
+                                 struct smb_file_time *ft)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_NTIMES(handle, path, ft);
+       result = SMB_VFS_NEXT_FNTIMES(handle, fsp, ft);
        clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("ntimes", timediff, path);
+               smb_time_audit_log_fsp("fntimes", timediff, fsp);
        }
 
        return result;
@@ -1359,22 +1335,50 @@ static bool smb_time_audit_lock(vfs_handle_struct *handle, files_struct *fsp,
        return result;
 }
 
-static int smb_time_audit_kernel_flock(struct vfs_handle_struct *handle,
-                                      struct files_struct *fsp,
-                                      uint32_t share_mode, uint32_t access_mask)
+static int smb_time_audit_filesystem_sharemode(struct vfs_handle_struct *handle,
+                                              struct files_struct *fsp,
+                                              uint32_t share_access,
+                                              uint32_t access_mask)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_KERNEL_FLOCK(handle, fsp, share_mode,
-                                          access_mask);
+       result = SMB_VFS_NEXT_FILESYSTEM_SHAREMODE(handle,
+                                                  fsp,
+                                                  share_access,
+                                                  access_mask);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("kernel_flock", timediff, fsp);
+               smb_time_audit_log_fsp("filesystem_sharemode", timediff, fsp);
+       }
+
+       return result;
+}
+
+static int smb_time_audit_fcntl(struct vfs_handle_struct *handle,
+                               struct files_struct *fsp,
+                               int cmd, va_list cmd_arg)
+{
+       void *arg;
+       va_list dup_cmd_arg;
+       int result;
+       struct timespec ts1,ts2;
+       double timediff;
+
+       va_copy(dup_cmd_arg, cmd_arg);
+       arg = va_arg(dup_cmd_arg, void *);
+       clock_gettime_mono(&ts1);
+       result = SMB_VFS_NEXT_FCNTL(handle, fsp, cmd, arg);
+       clock_gettime_mono(&ts2);
+       va_end(dup_cmd_arg);
+
+       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       if (timediff > audit_timeout) {
+               smb_time_audit_log_fsp("fcntl", timediff, fsp);
        }
 
        return result;
@@ -1422,107 +1426,176 @@ static bool smb_time_audit_getlock(vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_time_audit_symlink(vfs_handle_struct *handle,
-                                 const char *oldpath, const char *newpath)
+static int smb_time_audit_symlinkat(vfs_handle_struct *handle,
+                               const struct smb_filename *link_contents,
+                               struct files_struct *dirfsp,
+                               const struct smb_filename *new_smb_fname)
 {
+       struct smb_filename *full_fname = NULL;
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               new_smb_fname);
+       if (full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYMLINK(handle, oldpath, newpath);
+       result = SMB_VFS_NEXT_SYMLINKAT(handle,
+                               link_contents,
+                               dirfsp,
+                               new_smb_fname);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("symlink", timediff, newpath);
+               smb_time_audit_log_fname("symlinkat", timediff,
+                       full_fname->base_name);
        }
 
+       TALLOC_FREE(full_fname);
        return result;
 }
 
-static int smb_time_audit_readlink(vfs_handle_struct *handle,
-                         const char *path, char *buf, size_t bufsiz)
+static int smb_time_audit_readlinkat(vfs_handle_struct *handle,
+                               const struct files_struct *dirfsp,
+                               const struct smb_filename *smb_fname,
+                               char *buf,
+                               size_t bufsiz)
 {
+       struct smb_filename *full_fname = NULL;
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                               dirfsp,
+                                               smb_fname);
+       if (full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_READLINK(handle, path, buf, bufsiz);
+       result = SMB_VFS_NEXT_READLINKAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               buf,
+                               bufsiz);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("readlink", timediff, path);
+               smb_time_audit_log_fname("readlinkat", timediff,
+                               full_fname->base_name);
        }
 
+       TALLOC_FREE(full_fname);
        return result;
 }
 
-static int smb_time_audit_link(vfs_handle_struct *handle,
+static int smb_time_audit_linkat(vfs_handle_struct *handle,
+                               files_struct *srcfsp,
                                const struct smb_filename *old_smb_fname,
-                               const struct smb_filename *new_smb_fname)
+                               files_struct *dstfsp,
+                               const struct smb_filename *new_smb_fname,
+                               int flags)
 {
+       struct smb_filename *new_full_fname = NULL;
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
+       new_full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dstfsp,
+                                                 new_smb_fname);
+       if (new_full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_LINK(handle, old_smb_fname, new_smb_fname);
+       result = SMB_VFS_NEXT_LINKAT(handle,
+                       srcfsp,
+                       old_smb_fname,
+                       dstfsp,
+                       new_smb_fname,
+                       flags);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("link", timediff,
-                       new_smb_fname->base_name);
+               smb_time_audit_log_fname("linkat", timediff,
+                       new_full_fname->base_name);
        }
 
+       TALLOC_FREE(new_full_fname);
        return result;
 }
 
-static int smb_time_audit_mknod(vfs_handle_struct *handle,
+static int smb_time_audit_mknodat(vfs_handle_struct *handle,
+                               files_struct *dirfsp,
                                const struct smb_filename *smb_fname,
                                mode_t mode,
                                SMB_DEV_T dev)
 {
+       struct smb_filename *full_fname = NULL;
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
+       full_fname = full_path_from_dirfsp_atname(talloc_tos(),
+                                                 dirfsp,
+                                                 smb_fname);
+       if (full_fname == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_MKNOD(handle, smb_fname, mode, dev);
+       result = SMB_VFS_NEXT_MKNODAT(handle,
+                               dirfsp,
+                               smb_fname,
+                               mode,
+                               dev);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("mknod", timediff, smb_fname);
+               smb_time_audit_log_smb_fname("mknodat", timediff, full_fname);
        }
 
+       TALLOC_FREE(full_fname);
        return result;
 }
 
-static char *smb_time_audit_realpath(vfs_handle_struct *handle,
-                                    const char *path)
+static struct smb_filename *smb_time_audit_realpath(vfs_handle_struct *handle,
+                               TALLOC_CTX *ctx,
+                               const struct smb_filename *smb_fname)
 {
-       char *result;
+       struct smb_filename *result_fname;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_REALPATH(handle, path);
+       result_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, smb_fname);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("realpath", timediff, path);
+               smb_time_audit_log_fname("realpath", timediff,
+                               smb_fname->base_name);
        }
 
-       return result;
+       return result_fname;
 }
 
-static int smb_time_audit_chflags(vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname,
+static int smb_time_audit_fchflags(vfs_handle_struct *handle,
+                               struct files_struct *fsp,
                                unsigned int flags)
 {
        int result;
@@ -1530,12 +1603,14 @@ static int smb_time_audit_chflags(vfs_handle_struct *handle,
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_CHFLAGS(handle, smb_fname, flags);
+       result = SMB_VFS_NEXT_FCHFLAGS(handle, fsp, flags);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("chflags", timediff, smb_fname);
+               smb_time_audit_log_smb_fname("chflags",
+                                            timediff,
+                                            fsp->fsp_name);
        }
 
        return result;
@@ -1563,194 +1638,204 @@ static struct file_id smb_time_audit_file_id_create(struct vfs_handle_struct *ha
        return result;
 }
 
-static NTSTATUS smb_time_audit_streaminfo(vfs_handle_struct *handle,
-                                         struct files_struct *fsp,
-                                         const struct smb_filename *smb_fname,
-                                         TALLOC_CTX *mem_ctx,
-                                         unsigned int *pnum_streams,
-                                         struct stream_struct **pstreams)
+static uint64_t smb_time_audit_fs_file_id(struct vfs_handle_struct *handle,
+                                         const SMB_STRUCT_STAT *sbuf)
 {
-       NTSTATUS result;
+       uint64_t result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_STREAMINFO(handle, fsp, smb_fname, mem_ctx,
-                                        pnum_streams, pstreams);
+       result = SMB_VFS_NEXT_FS_FILE_ID(handle, sbuf);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("streaminfo", timediff, fsp);
+               smb_time_audit_log("fs_file_id", timediff);
        }
 
        return result;
 }
 
-static int smb_time_audit_get_real_filename(struct vfs_handle_struct *handle,
-                                           const char *path,
-                                           const char *name,
-                                           TALLOC_CTX *mem_ctx,
-                                           char **found_name)
+static NTSTATUS smb_time_audit_fstreaminfo(vfs_handle_struct *handle,
+                                         struct files_struct *fsp,
+                                         TALLOC_CTX *mem_ctx,
+                                         unsigned int *pnum_streams,
+                                         struct stream_struct **pstreams)
 {
-       int result;
+       NTSTATUS result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx,
-                                               found_name);
+       result = SMB_VFS_NEXT_FSTREAMINFO(handle, fsp, mem_ctx,
+                                        pnum_streams, pstreams);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("get_real_filename", timediff, path);
+               smb_time_audit_log_fsp("fstreaminfo", timediff, fsp);
        }
 
        return result;
 }
 
-static const char *smb_time_audit_connectpath(vfs_handle_struct *handle,
-                                             const char *fname)
+static NTSTATUS smb_time_audit_get_real_filename_at(
+       struct vfs_handle_struct *handle,
+       struct files_struct *dirfsp,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
-       const char *result;
+       NTSTATUS result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_CONNECTPATH(handle, fname);
+       result = SMB_VFS_NEXT_GET_REAL_FILENAME_AT(
+               handle, dirfsp, name, mem_ctx, found_name);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("connectpath", timediff, fname);
+               smb_time_audit_log_fname("get_real_filename_at",
+                                        timediff,
+                                        fsp_str_dbg(dirfsp));
        }
 
        return result;
 }
 
-static NTSTATUS smb_time_audit_brl_lock_windows(struct vfs_handle_struct *handle,
-                                               struct byte_range_lock *br_lck,
-                                               struct lock_struct *plock,
-                                               bool blocking_lock)
+static const char *smb_time_audit_connectpath(
+       vfs_handle_struct *handle,
+       const struct files_struct *dirfsp,
+       const struct smb_filename *smb_fname)
 {
-       NTSTATUS result;
+       const char *result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock,
-                                              blocking_lock);
+       result = SMB_VFS_NEXT_CONNECTPATH(handle, dirfsp, smb_fname);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("brl_lock_windows", timediff,
-                                      brl_fsp(br_lck));
+               smb_time_audit_log_fname("connectpath", timediff,
+                       smb_fname->base_name);
        }
 
        return result;
 }
 
-static bool smb_time_audit_brl_unlock_windows(struct vfs_handle_struct *handle,
-                                             struct messaging_context *msg_ctx,
-                                             struct byte_range_lock *br_lck,
-                                             const struct lock_struct *plock)
+static NTSTATUS smb_time_audit_brl_lock_windows(struct vfs_handle_struct *handle,
+                                               struct byte_range_lock *br_lck,
+                                               struct lock_struct *plock)
 {
-       bool result;
+       NTSTATUS result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, msg_ctx, br_lck,
-                                                plock);
+       result = SMB_VFS_NEXT_BRL_LOCK_WINDOWS(handle, br_lck, plock);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("brl_unlock_windows", timediff,
+               smb_time_audit_log_fsp("brl_lock_windows", timediff,
                                       brl_fsp(br_lck));
        }
 
        return result;
 }
 
-static bool smb_time_audit_brl_cancel_windows(struct vfs_handle_struct *handle,
+static bool smb_time_audit_brl_unlock_windows(struct vfs_handle_struct *handle,
                                              struct byte_range_lock *br_lck,
-                                             struct lock_struct *plock)
+                                             const struct lock_struct *plock)
 {
        bool result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_BRL_CANCEL_WINDOWS(handle, br_lck, plock);
+       result = SMB_VFS_NEXT_BRL_UNLOCK_WINDOWS(handle, br_lck, plock);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("brl_cancel_windows", timediff,
+               smb_time_audit_log_fsp("brl_unlock_windows", timediff,
                                       brl_fsp(br_lck));
        }
 
        return result;
 }
 
-static bool smb_time_audit_strict_lock(struct vfs_handle_struct *handle,
-                                      struct files_struct *fsp,
-                                      struct lock_struct *plock)
+static bool smb_time_audit_strict_lock_check(struct vfs_handle_struct *handle,
+                                            struct files_struct *fsp,
+                                            struct lock_struct *plock)
 {
        bool result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_STRICT_LOCK(handle, fsp, plock);
+       result = SMB_VFS_NEXT_STRICT_LOCK_CHECK(handle, fsp, plock);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("strict_lock", timediff, fsp);
+               smb_time_audit_log_fsp("strict_lock_check", timediff, fsp);
        }
 
        return result;
 }
 
-static void smb_time_audit_strict_unlock(struct vfs_handle_struct *handle,
-                                        struct files_struct *fsp,
-                                        struct lock_struct *plock)
+static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle,
+                                             const char *name,
+                                             enum vfs_translate_direction direction,
+                                             TALLOC_CTX *mem_ctx,
+                                             char **mapped_name)
 {
+       NTSTATUS result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock);
+       result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx,
+                                            mapped_name);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("strict_unlock", timediff, fsp);
+               smb_time_audit_log_fname("translate_name", timediff, name);
        }
+
+       return result;
 }
 
-static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle,
-                                             const char *name,
-                                             enum vfs_translate_direction direction,
-                                             TALLOC_CTX *mem_ctx,
-                                             char **mapped_name)
+static NTSTATUS smb_time_audit_parent_pathname(struct vfs_handle_struct *handle,
+                                              TALLOC_CTX *mem_ctx,
+                                              const struct smb_filename *smb_fname_in,
+                                              struct smb_filename **parent_dir_out,
+                                              struct smb_filename **atname_out)
 {
        NTSTATUS result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx,
-                                            mapped_name);
+       result = SMB_VFS_NEXT_PARENT_PATHNAME(handle,
+                                             mem_ctx,
+                                             smb_fname_in,
+                                             parent_dir_out,
+                                             atname_out);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("translate_name", timediff, name);
+               smb_time_audit_log_fname("parent_pathname",
+                                        timediff,
+                                        smb_fname_in->base_name);
        }
 
        return result;
@@ -1792,28 +1877,101 @@ static NTSTATUS smb_time_audit_fsctl(struct vfs_handle_struct *handle,
        return result;
 }
 
-static NTSTATUS smb_time_get_dos_attributes(struct vfs_handle_struct *handle,
-                                       struct smb_filename *smb_fname,
-                                       uint32_t *dosmode)
+struct smb_time_audit_get_dos_attributes_state {
+       struct vfs_aio_state aio_state;
+       files_struct *dir_fsp;
+       const struct smb_filename *smb_fname;
+       uint32_t dosmode;
+};
+
+static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_time_audit_get_dos_attributes_send(
+                       TALLOC_CTX *mem_ctx,
+                       struct tevent_context *ev,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       struct smb_filename *smb_fname)
 {
-       NTSTATUS result;
-       struct timespec ts1,ts2;
+       struct tevent_req *req = NULL;
+       struct smb_time_audit_get_dos_attributes_state *state = NULL;
+       struct tevent_req *subreq = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb_time_audit_get_dos_attributes_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       *state = (struct smb_time_audit_get_dos_attributes_state) {
+               .dir_fsp = dir_fsp,
+               .smb_fname = smb_fname,
+       };
+
+       subreq = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_SEND(mem_ctx,
+                                                     ev,
+                                                     handle,
+                                                     dir_fsp,
+                                                     smb_fname);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq,
+                               smb_time_audit_get_dos_attributes_done,
+                               req);
+
+       return req;
+}
+
+static void smb_time_audit_get_dos_attributes_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req =
+               tevent_req_callback_data(subreq,
+               struct tevent_req);
+       struct smb_time_audit_get_dos_attributes_state *state =
+               tevent_req_data(req,
+               struct smb_time_audit_get_dos_attributes_state);
+       NTSTATUS status;
+
+       status = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES_RECV(subreq,
+                                                     &state->aio_state,
+                                                     &state->dosmode);
+       TALLOC_FREE(subreq);
+       if (tevent_req_nterror(req, status)) {
+               return;
+       }
+
+       tevent_req_done(req);
+       return;
+}
+
+static NTSTATUS smb_time_audit_get_dos_attributes_recv(struct tevent_req *req,
+                                               struct vfs_aio_state *aio_state,
+                                               uint32_t *dosmode)
+{
+       struct smb_time_audit_get_dos_attributes_state *state =
+               tevent_req_data(req,
+               struct smb_time_audit_get_dos_attributes_state);
+       NTSTATUS status;
        double timediff;
 
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
-                               smb_fname,
-                               dosmode);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       timediff = state->aio_state.duration * 1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("get_dos_attributes",
-                               timediff,
-                               smb_fname->base_name);
+               smb_time_audit_log_at("async get_dos_attributes",
+                                     timediff,
+                                     state->dir_fsp,
+                                     state->smb_fname);
        }
 
-       return result;
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
+       }
+
+       *aio_state = state->aio_state;
+       *dosmode = state->dosmode;
+       tevent_req_received(req);
+       return NT_STATUS_OK;
 }
 
 static NTSTATUS smb_time_fget_dos_attributes(struct vfs_handle_struct *handle,
@@ -1838,8 +1996,8 @@ static NTSTATUS smb_time_fget_dos_attributes(struct vfs_handle_struct *handle,
        return result;
 }
 
-static NTSTATUS smb_time_set_dos_attributes(struct vfs_handle_struct *handle,
-                                       const struct smb_filename *smb_fname,
+static NTSTATUS smb_time_fset_dos_attributes(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
                                        uint32_t dosmode)
 {
        NTSTATUS result;
@@ -1847,93 +2005,169 @@ static NTSTATUS smb_time_set_dos_attributes(struct vfs_handle_struct *handle,
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
-                               smb_fname,
+       result = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle,
+                               fsp,
                                dosmode);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("set_dos_attributes",
-                               timediff,
-                               smb_fname->base_name);
+               smb_time_audit_log_fsp("fset_dos_attributes", timediff, fsp);
        }
 
        return result;
 }
 
-static NTSTATUS smb_time_fset_dos_attributes(struct vfs_handle_struct *handle,
-                                       struct files_struct *fsp,
-                                       uint32_t dosmode)
+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;
+};
+
+static void smb_time_audit_offload_read_done(struct tevent_req *subreq);
+
+static struct tevent_req *smb_time_audit_offload_read_send(
+       TALLOC_CTX *mem_ctx,
+       struct tevent_context *ev,
+       struct vfs_handle_struct *handle,
+       struct files_struct *fsp,
+       uint32_t fsctl,
+       uint32_t ttl,
+       off_t offset,
+       size_t to_copy)
 {
-       NTSTATUS result;
-       struct timespec ts1,ts2;
-       double timediff;
+       struct tevent_req *req = NULL;
+       struct tevent_req *subreq = NULL;
+       struct time_audit_offload_read_state *state = NULL;
 
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle,
-                               fsp,
-                               dosmode);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct time_audit_offload_read_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       state->handle = handle;
+       clock_gettime_mono(&state->ts_send);
+
+       subreq = SMB_VFS_NEXT_OFFLOAD_READ_SEND(mem_ctx, ev,
+                                               handle, fsp,
+                                               fsctl, ttl,
+                                               offset, to_copy);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       tevent_req_set_callback(subreq, smb_time_audit_offload_read_done, req);
+       return req;
+}
+
+static void smb_time_audit_offload_read_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct time_audit_offload_read_state *state = tevent_req_data(
+               req, struct time_audit_offload_read_state);
+       NTSTATUS status;
+
+       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)) {
+               return;
+       }
+       tevent_req_done(req);
+}
 
+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(
+               req, struct time_audit_offload_read_state);
+       struct timespec ts_recv;
+       double timediff;
+       NTSTATUS status;
+
+       clock_gettime_mono(&ts_recv);
+       timediff = nsec_time_diff(&ts_recv, &state->ts_send) * 1.0e-9;
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("fset_dos_attributes", timediff, fsp);
+               smb_time_audit_log("offload_read", timediff);
        }
 
-       return result;
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               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);
+
+       tevent_req_received(req);
+       return NT_STATUS_OK;
 }
 
-struct time_audit_cc_state {
+struct time_audit_offload_write_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 void smb_time_audit_offload_write_done(struct tevent_req *subreq);
 
-static struct tevent_req *smb_time_audit_copy_chunk_send(struct vfs_handle_struct *handle,
+static struct tevent_req *smb_time_audit_offload_write_send(struct vfs_handle_struct *handle,
                                                         TALLOC_CTX *mem_ctx,
                                                         struct tevent_context *ev,
-                                                        struct files_struct *src_fsp,
-                                                        off_t src_off,
+                                                        uint32_t fsctl,
+                                                        DATA_BLOB *token,
+                                                        off_t transfer_offset,
                                                         struct files_struct *dest_fsp,
                                                         off_t dest_off,
-                                                        off_t num,
-                                                        uint32_t flags)
+                                                        off_t num)
 {
        struct tevent_req *req;
        struct tevent_req *subreq;
-       struct time_audit_cc_state *cc_state;
+       struct time_audit_offload_write_state *state;
 
-       req = tevent_req_create(mem_ctx, &cc_state, struct time_audit_cc_state);
+       req = tevent_req_create(mem_ctx, &state,
+                               struct time_audit_offload_write_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, flags);
+       state->handle = handle;
+       clock_gettime_mono(&state->ts_send);
+       subreq = SMB_VFS_NEXT_OFFLOAD_WRITE_SEND(handle, state, ev,
+                                             fsctl, token, transfer_offset,
+                                             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);
+       tevent_req_set_callback(subreq, smb_time_audit_offload_write_done, req);
        return req;
 }
 
-static void smb_time_audit_copy_chunk_done(struct tevent_req *subreq)
+static void smb_time_audit_offload_write_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);
+       struct time_audit_offload_write_state *state = tevent_req_data(
+               req, struct time_audit_offload_write_state);
        NTSTATUS status;
 
-       status = SMB_VFS_NEXT_COPY_CHUNK_RECV(cc_state->handle,
+       status = SMB_VFS_NEXT_OFFLOAD_WRITE_RECV(state->handle,
                                              subreq,
-                                             &cc_state->copied);
+                                             &state->copied);
        TALLOC_FREE(subreq);
        if (tevent_req_nterror(req, status)) {
                return;
@@ -1941,23 +2175,23 @@ static void smb_time_audit_copy_chunk_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
-static NTSTATUS smb_time_audit_copy_chunk_recv(struct vfs_handle_struct *handle,
+static NTSTATUS smb_time_audit_offload_write_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 time_audit_offload_write_state *state = tevent_req_data(
+               req, struct time_audit_offload_write_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;
+       timediff = nsec_time_diff(&ts_recv, &state->ts_send)*1.0e-9;
        if (timediff > audit_timeout) {
-               smb_time_audit_log("copy_chunk", timediff);
+               smb_time_audit_log("offload_write", timediff);
        }
 
-       *copied = cc_state->copied;
+       *copied = state->copied;
        if (tevent_req_is_nterror(req, &status)) {
                tevent_req_received(req);
                return status;
@@ -1967,10 +2201,9 @@ static NTSTATUS smb_time_audit_copy_chunk_recv(struct vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-static NTSTATUS smb_time_audit_get_compression(vfs_handle_struct *handle,
+static NTSTATUS smb_time_audit_fget_compression(vfs_handle_struct *handle,
                                               TALLOC_CTX *mem_ctx,
                                               struct files_struct *fsp,
-                                              struct smb_filename *smb_fname,
                                               uint16_t *_compression_fmt)
 {
        NTSTATUS result;
@@ -1978,19 +2211,14 @@ static NTSTATUS smb_time_audit_get_compression(vfs_handle_struct *handle,
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GET_COMPRESSION(handle, mem_ctx, fsp, smb_fname,
+       result = SMB_VFS_NEXT_FGET_COMPRESSION(handle, mem_ctx, fsp,
                                              _compression_fmt);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               if (fsp !=  NULL) {
-                       smb_time_audit_log_fsp("get_compression",
-                                              timediff, fsp);
-               } else {
-                       smb_time_audit_log_smb_fname("get_compression",
-                                                    timediff, smb_fname);
-               }
+               smb_time_audit_log_fsp("get_compression",
+                                      timediff, fsp);
        }
 
        return result;
@@ -2018,22 +2246,22 @@ static NTSTATUS smb_time_audit_set_compression(vfs_handle_struct *handle,
        return result;
 }
 
-static NTSTATUS smb_time_audit_readdir_attr(struct vfs_handle_struct *handle,
-                                           const struct smb_filename *fname,
-                                           TALLOC_CTX *mem_ctx,
-                                           struct readdir_attr_data **pattr_data)
+static NTSTATUS smb_time_audit_freaddir_attr(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct readdir_attr_data **pattr_data)
 {
        NTSTATUS status;
-       struct timespec ts1,ts2;
+       struct timespec ts1, ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       status = SMB_VFS_NEXT_READDIR_ATTR(handle, fname, mem_ctx, pattr_data);
+       status = SMB_VFS_NEXT_FREADDIR_ATTR(handle, fsp, mem_ctx, pattr_data);
        clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       timediff = nsec_time_diff(&ts2, &ts1) * 1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_smb_fname("readdir_attr", timediff, fname);
+               smb_time_audit_log_fsp("freaddir_attr", timediff, fsp);
        }
 
        return status;
@@ -2062,31 +2290,6 @@ static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle,
        return result;
 }
 
-static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle,
-                                         const struct smb_filename *smb_fname,
-                                         uint32_t security_info,
-                                         TALLOC_CTX *mem_ctx,
-                                         struct security_descriptor **ppdesc)
-{
-       NTSTATUS result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GET_NT_ACL(handle, smb_fname, security_info,
-                                        mem_ctx, ppdesc);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("get_nt_acl",
-                       timediff,
-                       smb_fname->base_name);
-       }
-
-       return result;
-}
-
 static NTSTATUS smb_time_audit_fset_nt_acl(vfs_handle_struct *handle,
                                           files_struct *fsp,
                                           uint32_t security_info_sent,
@@ -2137,74 +2340,9 @@ static NTSTATUS smb_time_audit_audit_file(struct vfs_handle_struct *handle,
        return result;
 }
 
-
-
-static int smb_time_audit_chmod_acl(vfs_handle_struct *handle,
-                       const struct smb_filename *smb_fname,
-                       mode_t mode)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_CHMOD_ACL(handle, smb_fname, mode);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("chmod_acl",
-                       timediff,
-                       smb_fname->base_name);
-       }
-
-       return result;
-}
-
-static int smb_time_audit_fchmod_acl(vfs_handle_struct *handle,
-                                    files_struct *fsp, mode_t mode)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("fchmod_acl", timediff, fsp);
-       }
-
-       return result;
-}
-
-static SMB_ACL_T smb_time_audit_sys_acl_get_file(vfs_handle_struct *handle,
-                                       const struct smb_filename *smb_fname,
-                                       SMB_ACL_TYPE_T type,
-                                       TALLOC_CTX *mem_ctx)
-{
-       SMB_ACL_T result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
-                               type, mem_ctx);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("sys_acl_get_file", timediff,
-                       smb_fname->base_name);
-       }
-
-       return result;
-}
-
 static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
                                               files_struct *fsp,
+                                              SMB_ACL_TYPE_T type,
                                               TALLOC_CTX *mem_ctx)
 {
        SMB_ACL_T result;
@@ -2212,7 +2350,7 @@ static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
+       result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, type, mem_ctx);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
@@ -2223,30 +2361,6 @@ static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle,
        return result;
 }
 
-
-static int smb_time_audit_sys_acl_blob_get_file(vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname,
-                               TALLOC_CTX *mem_ctx,
-                               char **blob_description,
-                               DATA_BLOB *blob)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname,
-                               mem_ctx, blob_description, blob);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log("sys_acl_blob_get_file", timediff);
-       }
-
-       return result;
-}
-
 static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
                                              files_struct *fsp,
                                              TALLOC_CTX *mem_ctx, 
@@ -2269,116 +2383,153 @@ static int smb_time_audit_sys_acl_blob_get_fd(vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_time_audit_sys_acl_set_file(vfs_handle_struct *handle,
-                                          const struct smb_filename *smb_fname,
-                                          SMB_ACL_TYPE_T acltype,
-                                          SMB_ACL_T theacl)
+static int smb_time_audit_sys_acl_set_fd(vfs_handle_struct *handle,
+                                        files_struct *fsp,
+                                        SMB_ACL_TYPE_T type,
+                                        SMB_ACL_T theacl)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, smb_fname, acltype,
-                                              theacl);
+       result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, type, theacl);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("sys_acl_set_file", timediff,
-                       smb_fname->base_name);
+               smb_time_audit_log_fsp("sys_acl_set_fd", timediff, fsp);
        }
 
        return result;
 }
 
-static int smb_time_audit_sys_acl_set_fd(vfs_handle_struct *handle,
-                                        files_struct *fsp,
-                                        SMB_ACL_T theacl)
+static int smb_time_audit_sys_acl_delete_def_fd(vfs_handle_struct *handle,
+                               files_struct *fsp)
 {
        int result;
        struct timespec ts1,ts2;
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYS_ACL_SET_FD(handle, fsp, theacl);
+       result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FD(handle, fsp);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("sys_acl_set_fd", timediff, fsp);
+               smb_time_audit_log_fsp("sys_acl_delete_def_fd", timediff, fsp);
        }
 
        return result;
 }
 
-static int smb_time_audit_sys_acl_delete_def_file(vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
+struct smb_time_audit_getxattrat_state {
+       struct vfs_aio_state aio_state;
+       files_struct *dir_fsp;
+       const struct smb_filename *smb_fname;
+       const char *xattr_name;
+       ssize_t xattr_size;
+       uint8_t *xattr_value;
+};
 
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+static void smb_time_audit_getxattrat_done(struct tevent_req *subreq);
 
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("sys_acl_delete_def_file", timediff,
-                       smb_fname->base_name);
+static struct tevent_req *smb_time_audit_getxattrat_send(
+                       TALLOC_CTX *mem_ctx,
+                       struct tevent_context *ev,
+                       struct vfs_handle_struct *handle,
+                       files_struct *dir_fsp,
+                       const struct smb_filename *smb_fname,
+                       const char *xattr_name,
+                       size_t alloc_hint)
+{
+       struct tevent_req *req = NULL;
+       struct tevent_req *subreq = NULL;
+       struct smb_time_audit_getxattrat_state *state = NULL;
+
+       req = tevent_req_create(mem_ctx, &state,
+                               struct smb_time_audit_getxattrat_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       *state = (struct smb_time_audit_getxattrat_state) {
+               .dir_fsp = dir_fsp,
+               .smb_fname = smb_fname,
+               .xattr_name = xattr_name,
+       };
+
+       subreq = SMB_VFS_NEXT_GETXATTRAT_SEND(state,
+                                             ev,
+                                             handle,
+                                             dir_fsp,
+                                             smb_fname,
+                                             xattr_name,
+                                             alloc_hint);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
        }
+       tevent_req_set_callback(subreq, smb_time_audit_getxattrat_done, req);
 
-       return result;
+       return req;
 }
 
-static ssize_t smb_time_audit_getxattr(struct vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname,
-                               const char *name,
-                               void *value,
-                               size_t size)
+static void smb_time_audit_getxattrat_done(struct tevent_req *subreq)
 {
-       ssize_t result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_GETXATTR(handle, smb_fname, name, value, size);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct smb_time_audit_getxattrat_state *state = tevent_req_data(
+               req, struct smb_time_audit_getxattrat_state);
 
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("getxattr", timediff,
-                       smb_fname->base_name);
+       state->xattr_size = SMB_VFS_NEXT_GETXATTRAT_RECV(subreq,
+                                                        &state->aio_state,
+                                                        state,
+                                                        &state->xattr_value);
+       TALLOC_FREE(subreq);
+       if (state->xattr_size == -1) {
+               tevent_req_error(req, state->aio_state.error);
+               return;
        }
 
-       return result;
+       tevent_req_done(req);
 }
 
-static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
-                                       struct files_struct *fsp,
-                                       const char *name, void *value,
-                                       size_t size)
+static ssize_t smb_time_audit_getxattrat_recv(struct tevent_req *req,
+                                             struct vfs_aio_state *aio_state,
+                                             TALLOC_CTX *mem_ctx,
+                                             uint8_t **xattr_value)
 {
-       ssize_t result;
-       struct timespec ts1,ts2;
+       struct smb_time_audit_getxattrat_state *state = tevent_req_data(
+               req, struct smb_time_audit_getxattrat_state);
+       ssize_t xattr_size;
        double timediff;
 
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
+       timediff = state->aio_state.duration * 1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fsp("fgetxattr", timediff, fsp);
+               smb_time_audit_log_at("async getxattrat",
+                                     timediff,
+                                     state->dir_fsp,
+                                     state->smb_fname);
        }
 
-       return result;
+       if (tevent_req_is_unix_error(req, &aio_state->error)) {
+               tevent_req_received(req);
+               return -1;
+       }
+
+       *aio_state = state->aio_state;
+       xattr_size = state->xattr_size;
+       if (xattr_value != NULL) {
+               *xattr_value = talloc_move(mem_ctx, &state->xattr_value);
+       }
+
+       tevent_req_received(req);
+       return xattr_size;
 }
 
-static ssize_t smb_time_audit_listxattr(struct vfs_handle_struct *handle,
-                                       const struct smb_filename *smb_fname,
-                                       char *list,
+static ssize_t smb_time_audit_fgetxattr(struct vfs_handle_struct *handle,
+                                       struct files_struct *fsp,
+                                       const char *name, void *value,
                                        size_t size)
 {
        ssize_t result;
@@ -2386,13 +2537,12 @@ static ssize_t smb_time_audit_listxattr(struct vfs_handle_struct *handle,
        double timediff;
 
        clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_LISTXATTR(handle, smb_fname, list, size);
+       result = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
        if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("listxattr", timediff,
-                               smb_fname->base_name);
+               smb_time_audit_log_fsp("fgetxattr", timediff, fsp);
        }
 
        return result;
@@ -2418,27 +2568,6 @@ static ssize_t smb_time_audit_flistxattr(struct vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_time_audit_removexattr(struct vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname,
-                               const char *name)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_REMOVEXATTR(handle, smb_fname, name);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("removexattr", timediff,
-                       smb_fname->base_name);
-       }
-
-       return result;
-}
-
 static int smb_time_audit_fremovexattr(struct vfs_handle_struct *handle,
                                       struct files_struct *fsp,
                                       const char *name)
@@ -2459,31 +2588,6 @@ static int smb_time_audit_fremovexattr(struct vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_time_audit_setxattr(struct vfs_handle_struct *handle,
-                               const struct smb_filename *smb_fname,
-                               const char *name,
-                               const void *value,
-                               size_t size,
-                               int flags)
-{
-       int result;
-       struct timespec ts1,ts2;
-       double timediff;
-
-       clock_gettime_mono(&ts1);
-       result = SMB_VFS_NEXT_SETXATTR(handle, smb_fname, name, value, size,
-                                      flags);
-       clock_gettime_mono(&ts2);
-       timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
-
-       if (timediff > audit_timeout) {
-               smb_time_audit_log_fname("setxattr", timediff,
-                               smb_fname->base_name);
-       }
-
-       return result;
-}
-
 static int smb_time_audit_fsetxattr(struct vfs_handle_struct *handle,
                                    struct files_struct *fsp, const char *name,
                                    const void *value, size_t size, int flags)
@@ -2604,111 +2708,99 @@ static struct vfs_fn_pointers vfs_time_audit_fns = {
        .statvfs_fn = smb_time_audit_statvfs,
        .fs_capabilities_fn = smb_time_audit_fs_capabilities,
        .get_dfs_referrals_fn = smb_time_audit_get_dfs_referrals,
-       .opendir_fn = smb_time_audit_opendir,
+       .create_dfs_pathat_fn = smb_time_audit_create_dfs_pathat,
+       .read_dfs_pathat_fn = smb_time_audit_read_dfs_pathat,
        .fdopendir_fn = smb_time_audit_fdopendir,
        .readdir_fn = smb_time_audit_readdir,
-       .seekdir_fn = smb_time_audit_seekdir,
-       .telldir_fn = smb_time_audit_telldir,
        .rewind_dir_fn = smb_time_audit_rewinddir,
-       .mkdir_fn = smb_time_audit_mkdir,
-       .rmdir_fn = smb_time_audit_rmdir,
+       .mkdirat_fn = smb_time_audit_mkdirat,
        .closedir_fn = smb_time_audit_closedir,
-       .init_search_op_fn = smb_time_audit_init_search_op,
-       .open_fn = smb_time_audit_open,
+       .openat_fn = smb_time_audit_openat,
        .create_file_fn = smb_time_audit_create_file,
        .close_fn = smb_time_audit_close,
-       .read_fn = smb_time_audit_read,
        .pread_fn = smb_time_audit_pread,
        .pread_send_fn = smb_time_audit_pread_send,
        .pread_recv_fn = smb_time_audit_pread_recv,
-       .write_fn = smb_time_audit_write,
        .pwrite_fn = smb_time_audit_pwrite,
        .pwrite_send_fn = smb_time_audit_pwrite_send,
        .pwrite_recv_fn = smb_time_audit_pwrite_recv,
        .lseek_fn = smb_time_audit_lseek,
        .sendfile_fn = smb_time_audit_sendfile,
        .recvfile_fn = smb_time_audit_recvfile,
-       .rename_fn = smb_time_audit_rename,
-       .fsync_fn = smb_time_audit_fsync,
+       .renameat_fn = smb_time_audit_renameat,
        .fsync_send_fn = smb_time_audit_fsync_send,
        .fsync_recv_fn = smb_time_audit_fsync_recv,
        .stat_fn = smb_time_audit_stat,
        .fstat_fn = smb_time_audit_fstat,
        .lstat_fn = smb_time_audit_lstat,
+       .fstatat_fn = smb_time_audit_fstatat,
        .get_alloc_size_fn = smb_time_audit_get_alloc_size,
-       .unlink_fn = smb_time_audit_unlink,
-       .chmod_fn = smb_time_audit_chmod,
+       .unlinkat_fn = smb_time_audit_unlinkat,
        .fchmod_fn = smb_time_audit_fchmod,
-       .chown_fn = smb_time_audit_chown,
        .fchown_fn = smb_time_audit_fchown,
        .lchown_fn = smb_time_audit_lchown,
        .chdir_fn = smb_time_audit_chdir,
        .getwd_fn = smb_time_audit_getwd,
-       .ntimes_fn = smb_time_audit_ntimes,
+       .fntimes_fn = smb_time_audit_fntimes,
        .ftruncate_fn = smb_time_audit_ftruncate,
        .fallocate_fn = smb_time_audit_fallocate,
        .lock_fn = smb_time_audit_lock,
-       .kernel_flock_fn = smb_time_audit_kernel_flock,
+       .filesystem_sharemode_fn = smb_time_audit_filesystem_sharemode,
+       .fcntl_fn = smb_time_audit_fcntl,
        .linux_setlease_fn = smb_time_audit_linux_setlease,
        .getlock_fn = smb_time_audit_getlock,
-       .symlink_fn = smb_time_audit_symlink,
-       .readlink_fn = smb_time_audit_readlink,
-       .link_fn = smb_time_audit_link,
-       .mknod_fn = smb_time_audit_mknod,
+       .symlinkat_fn = smb_time_audit_symlinkat,
+       .readlinkat_fn = smb_time_audit_readlinkat,
+       .linkat_fn = smb_time_audit_linkat,
+       .mknodat_fn = smb_time_audit_mknodat,
        .realpath_fn = smb_time_audit_realpath,
-       .chflags_fn = smb_time_audit_chflags,
+       .fchflags_fn = smb_time_audit_fchflags,
        .file_id_create_fn = smb_time_audit_file_id_create,
-       .copy_chunk_send_fn = smb_time_audit_copy_chunk_send,
-       .copy_chunk_recv_fn = smb_time_audit_copy_chunk_recv,
-       .get_compression_fn = smb_time_audit_get_compression,
+       .fs_file_id_fn = smb_time_audit_fs_file_id,
+       .offload_read_send_fn = smb_time_audit_offload_read_send,
+       .offload_read_recv_fn = smb_time_audit_offload_read_recv,
+       .offload_write_send_fn = smb_time_audit_offload_write_send,
+       .offload_write_recv_fn = smb_time_audit_offload_write_recv,
+       .fget_compression_fn = smb_time_audit_fget_compression,
        .set_compression_fn = smb_time_audit_set_compression,
        .snap_check_path_fn = smb_time_audit_snap_check_path,
        .snap_create_fn = smb_time_audit_snap_create,
        .snap_delete_fn = smb_time_audit_snap_delete,
-       .streaminfo_fn = smb_time_audit_streaminfo,
-       .get_real_filename_fn = smb_time_audit_get_real_filename,
+       .fstreaminfo_fn = smb_time_audit_fstreaminfo,
+       .get_real_filename_at_fn = smb_time_audit_get_real_filename_at,
        .connectpath_fn = smb_time_audit_connectpath,
        .brl_lock_windows_fn = smb_time_audit_brl_lock_windows,
        .brl_unlock_windows_fn = smb_time_audit_brl_unlock_windows,
-       .brl_cancel_windows_fn = smb_time_audit_brl_cancel_windows,
-       .strict_lock_fn = smb_time_audit_strict_lock,
-       .strict_unlock_fn = smb_time_audit_strict_unlock,
+       .strict_lock_check_fn = smb_time_audit_strict_lock_check,
        .translate_name_fn = smb_time_audit_translate_name,
+       .parent_pathname_fn = smb_time_audit_parent_pathname,
        .fsctl_fn = smb_time_audit_fsctl,
-       .get_dos_attributes_fn = smb_time_get_dos_attributes,
+       .get_dos_attributes_send_fn = smb_time_audit_get_dos_attributes_send,
+       .get_dos_attributes_recv_fn = smb_time_audit_get_dos_attributes_recv,
        .fget_dos_attributes_fn = smb_time_fget_dos_attributes,
-       .set_dos_attributes_fn = smb_time_set_dos_attributes,
        .fset_dos_attributes_fn = smb_time_fset_dos_attributes,
        .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,
        .audit_file_fn = smb_time_audit_audit_file,
-       .chmod_acl_fn = smb_time_audit_chmod_acl,
-       .fchmod_acl_fn = smb_time_audit_fchmod_acl,
-       .sys_acl_get_file_fn = smb_time_audit_sys_acl_get_file,
        .sys_acl_get_fd_fn = smb_time_audit_sys_acl_get_fd,
-       .sys_acl_blob_get_file_fn = smb_time_audit_sys_acl_blob_get_file,
        .sys_acl_blob_get_fd_fn = smb_time_audit_sys_acl_blob_get_fd,
-       .sys_acl_set_file_fn = smb_time_audit_sys_acl_set_file,
        .sys_acl_set_fd_fn = smb_time_audit_sys_acl_set_fd,
-       .sys_acl_delete_def_file_fn = smb_time_audit_sys_acl_delete_def_file,
-       .getxattr_fn = smb_time_audit_getxattr,
+       .sys_acl_delete_def_fd_fn = smb_time_audit_sys_acl_delete_def_fd,
+       .getxattrat_send_fn = smb_time_audit_getxattrat_send,
+       .getxattrat_recv_fn = smb_time_audit_getxattrat_recv,
        .fgetxattr_fn = smb_time_audit_fgetxattr,
-       .listxattr_fn = smb_time_audit_listxattr,
        .flistxattr_fn = smb_time_audit_flistxattr,
-       .removexattr_fn = smb_time_audit_removexattr,
        .fremovexattr_fn = smb_time_audit_fremovexattr,
-       .setxattr_fn = smb_time_audit_setxattr,
        .fsetxattr_fn = smb_time_audit_fsetxattr,
        .aio_force_fn = smb_time_audit_aio_force,
        .durable_cookie_fn = smb_time_audit_durable_cookie,
        .durable_disconnect_fn = smb_time_audit_durable_disconnect,
        .durable_reconnect_fn = smb_time_audit_durable_reconnect,
-       .readdir_attr_fn = smb_time_audit_readdir_attr,
+       .freaddir_attr_fn = smb_time_audit_freaddir_attr,
 };
 
 
-NTSTATUS vfs_time_audit_init(TALLOC_CTX *);
+static_decl_vfs;
 NTSTATUS vfs_time_audit_init(TALLOC_CTX *ctx)
 {
        smb_vfs_assert_all_fns(&vfs_time_audit_fns, "time_audit");