vfs: Add dirfsp arg to SMB_VFS_READDIR()
authorRalph Boehme <slow@samba.org>
Sun, 22 Nov 2020 12:57:27 +0000 (13:57 +0100)
committerRalph Boehme <slow@samba.org>
Wed, 16 Dec 2020 09:08:31 +0000 (09:08 +0000)
This allows for optimisations in VFS module: by passing the dirfsp as an
additional arg, the function can check fsp->fsp_name->flags which may include eg
SMB_FILENAME_POSIX_PATH to trigger POSIX pathname processing.

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
20 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/include/vfs_macros.h
source3/modules/vfs_cap.c
source3/modules/vfs_ceph.c
source3/modules/vfs_default.c
source3/modules/vfs_dirsort.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_media_harmony.c
source3/modules/vfs_not_implemented.c
source3/modules/vfs_shadow_copy.c
source3/modules/vfs_shadow_copy2.c
source3/modules/vfs_time_audit.c
source3/modules/vfs_unityed_media.c
source3/modules/vfs_widelinks.c
source3/smbd/dir.c
source3/smbd/proto.h
source3/smbd/vfs.c

index 2a3a7301bdb7b3b80c42ce08d8ade1783ea929df..b74f7360dde661e6ecef88f6cba2b4934375a140 100644 (file)
@@ -156,7 +156,9 @@ static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static struct dirent *skel_readdir(vfs_handle_struct *handle,
-                                  DIR *dirp, SMB_STRUCT_STAT *sbuf)
+                                  struct files_struct *dirfsp,
+                                  DIR *dirp,
+                                  SMB_STRUCT_STAT *sbuf)
 {
        return NULL;
 }
index a86b3e7cd19583ee5195d3d658b6429d78cf1566..969f0572cf5c52d93fa249e97a370162886d0c24 100644 (file)
@@ -164,9 +164,11 @@ static DIR *skel_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static struct dirent *skel_readdir(vfs_handle_struct *handle,
-                                  DIR *dirp, SMB_STRUCT_STAT *sbuf)
+                                  struct files_struct *dirfsp,
+                                  DIR *dirp,
+                                  SMB_STRUCT_STAT *sbuf)
 {
-       return SMB_VFS_NEXT_READDIR(handle, dirp, sbuf);
+       return SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, sbuf);
 }
 
 static void skel_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset)
index ce971de8627f71539cab5ea94402125c74cd103e..3110cbd9fe8dfcd061fd988ef6b0cc80bdb72d3c 100644 (file)
  * Version 44 - Add 'is_fsa' flag to struct files_struct.
  * Version 44 - Add 'have_proc_fds' flag to struct connection_struct.
  * Version 44 - Add 'have_proc_fds' flag to struct files_struct.
+ * Version 44 - Add dirfsp arg to SMB_VFS_READDIR()
  */
 
 #define SMB_VFS_INTERFACE_VERSION 44
@@ -919,8 +920,9 @@ struct vfs_fn_pointers {
 
        DIR *(*fdopendir_fn)(struct vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32_t attributes);
        struct dirent *(*readdir_fn)(struct vfs_handle_struct *handle,
-                                        DIR *dirp,
-                                        SMB_STRUCT_STAT *sbuf);
+                                    struct files_struct *dirfsp,
+                                    DIR *dirp,
+                                    SMB_STRUCT_STAT *sbuf);
        void (*seekdir_fn)(struct vfs_handle_struct *handle, DIR *dirp, long offset);
        long (*telldir_fn)(struct vfs_handle_struct *handle, DIR *dirp);
        void (*rewind_dir_fn)(struct vfs_handle_struct *handle, DIR *dirp);
@@ -1432,8 +1434,9 @@ DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
                                        const char *mask,
                                        uint32_t attributes);
 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
-                                       DIR *dirp,
-                                       SMB_STRUCT_STAT *sbuf);
+                                   struct files_struct *dirfsp,
+                                   DIR *dirp,
+                                   SMB_STRUCT_STAT *sbuf);
 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,
                          DIR *dirp, long offset);
 long smb_vfs_call_telldir(struct vfs_handle_struct *handle,
@@ -1894,7 +1897,9 @@ NTSTATUS vfs_not_implemented_snap_delete(struct vfs_handle_struct *handle,
 DIR *vfs_not_implemented_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
                                   const char *mask, uint32_t attr);
 struct dirent *vfs_not_implemented_readdir(vfs_handle_struct *handle,
-                                          DIR *dirp, SMB_STRUCT_STAT *sbuf);
+                                          struct files_struct *dirfsp,
+                                          DIR *dirp,
+                                          SMB_STRUCT_STAT *sbuf);
 void vfs_not_implemented_seekdir(vfs_handle_struct *handle, DIR *dirp, long offset);
 long vfs_not_implemented_telldir(vfs_handle_struct *handle, DIR *dirp);
 void vfs_not_implemented_rewind_dir(vfs_handle_struct *handle, DIR *dirp);
index 70d9ab6784cab6d95c92b7a9e3b98c4afe12f104..f3ffe8566c793dded3d7ae665acf9c823945d50a 100644 (file)
 #define SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask, attr) \
        smb_vfs_call_fdopendir((handle)->next, (fsp), (mask), (attr))
 
-#define SMB_VFS_READDIR(conn, dirp, sbuf) \
-       smb_vfs_call_readdir((conn)->vfs_handles, (dirp), (sbuf))
-#define SMB_VFS_NEXT_READDIR(handle, dirp, sbuf) \
-       smb_vfs_call_readdir((handle)->next, (dirp), (sbuf))
+#define SMB_VFS_READDIR(conn, dirfsp, dirp, sbuf) \
+       smb_vfs_call_readdir((conn)->vfs_handles, (dirfsp), (dirp), (sbuf))
+#define SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, sbuf) \
+       smb_vfs_call_readdir((handle)->next, (dirfsp), (dirp), (sbuf))
 
 #define SMB_VFS_SEEKDIR(conn, dirp, offset) \
        smb_vfs_call_seekdir((conn)->vfs_handles, (dirp), (offset))
index 5deb7754f02eaa5c6334c2cb1150804fccbc93da..c40d2a25b761b86c0439cc2cb7d0778e16fea871 100644 (file)
@@ -85,8 +85,9 @@ static int cap_get_quota(vfs_handle_struct *handle,
 }
 
 static struct dirent *cap_readdir(vfs_handle_struct *handle,
-                                     DIR *dirp,
-                                     SMB_STRUCT_STAT *sbuf)
+                                 struct files_struct *dirfsp,
+                                 DIR *dirp,
+                                 SMB_STRUCT_STAT *sbuf)
 {
        struct dirent *result;
        struct dirent *newdirent;
@@ -94,7 +95,7 @@ static struct dirent *cap_readdir(vfs_handle_struct *handle,
        size_t newnamelen;
        DEBUG(3,("cap: cap_readdir\n"));
 
-       result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
+       result = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, NULL);
        if (!result) {
                return NULL;
        }
index 502b72359b3aa5350a4d4bb9faad4e4343829c1e..4c380c3ad20d91027f62ec7221b6d40cb6b21a95 100644 (file)
@@ -321,6 +321,7 @@ static DIR *cephwrap_fdopendir(struct vfs_handle_struct *handle,
 }
 
 static struct dirent *cephwrap_readdir(struct vfs_handle_struct *handle,
+                                      struct files_struct *dirfsp,
                                       DIR *dirp,
                                       SMB_STRUCT_STAT *sbuf)
 {
index 21075d725a97242d334b9c62bd9b13159de3b910..929c4ce7d0e267801f00740d67e15ed0bee46c2c 100644 (file)
@@ -571,8 +571,9 @@ static DIR *vfswrap_fdopendir(vfs_handle_struct *handle,
 
 
 static struct dirent *vfswrap_readdir(vfs_handle_struct *handle,
-                                         DIR *dirp,
-                                         SMB_STRUCT_STAT *sbuf)
+                                     struct files_struct *dirfsp,
+                                     DIR *dirp,
+                                     SMB_STRUCT_STAT *sbuf)
 {
        struct dirent *result;
 
index 3b3d609563df9e04af9b7c904610e11a3e6070f6..d9cfcadacf84e0b89d6b83331725e93f29970fa6 100644 (file)
@@ -79,7 +79,10 @@ static bool open_and_sort_dir(vfs_handle_struct *handle,
                return false;
        }
 
-       dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL);
+       dp = SMB_VFS_NEXT_READDIR(handle,
+                                 data->fsp,
+                                 data->source_directory,
+                                 NULL);
        if (dp == NULL) {
                return false;
        }
@@ -120,7 +123,10 @@ static bool open_and_sort_dir(vfs_handle_struct *handle,
                data->directory_list[total_count] = *dp;
 
                total_count++;
-               dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL);
+               dp = SMB_VFS_NEXT_READDIR(handle,
+                                         data->fsp,
+                                         data->source_directory,
+                                         NULL);
        } while (dp != NULL);
 
        data->number_of_entries = total_count;
@@ -178,8 +184,9 @@ static DIR *dirsort_fdopendir(vfs_handle_struct *handle,
 }
 
 static struct dirent *dirsort_readdir(vfs_handle_struct *handle,
-                                         DIR *dirp,
-                                         SMB_STRUCT_STAT *sbuf)
+                                     struct files_struct *dirfsp,
+                                     DIR *dirp,
+                                     SMB_STRUCT_STAT *sbuf)
 {
        struct dirsort_privates *data = NULL;
        struct timespec current_mtime;
index f1823e3b22e3a4575c7e426a2bd7cf484e21bc50..5a73562a09a1bf0c14156c1f04645563a9b05582 100644 (file)
@@ -1004,11 +1004,13 @@ static DIR *smb_full_audit_fdopendir(vfs_handle_struct *handle,
 }
 
 static struct dirent *smb_full_audit_readdir(vfs_handle_struct *handle,
-                                   DIR *dirp, SMB_STRUCT_STAT *sbuf)
+                                            struct files_struct *dirfsp,
+                                            DIR *dirp,
+                                            SMB_STRUCT_STAT *sbuf)
 {
        struct dirent *result;
 
-       result = SMB_VFS_NEXT_READDIR(handle, dirp, sbuf);
+       result = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, sbuf);
 
        /* This operation has no reasonable error condition
         * (End of dir is also failure), so always succeed.
index e4c129319385f15a19c4ed259b855ee34106caee..b5896feefbd40ddd85abcab71134fe648501de93 100644 (file)
@@ -650,7 +650,9 @@ static int vfs_gluster_closedir(struct vfs_handle_struct *handle, DIR *dirp)
 }
 
 static struct dirent *vfs_gluster_readdir(struct vfs_handle_struct *handle,
-                                         DIR *dirp, SMB_STRUCT_STAT *sbuf)
+                                         struct files_struct *dirfsp,
+                                         DIR *dirp,
+                                         SMB_STRUCT_STAT *sbuf)
 {
        static char direntbuf[512];
        int ret;
index 12e7ad61806be7aab5242d7e5bf05d04c2272995..79fc595339eeb5b77a581e25ecaa6481ee2d4c75 100644 (file)
@@ -818,8 +818,9 @@ err:
  * Failure: set errno, return NULL
  */
 static struct dirent *mh_readdir(vfs_handle_struct *handle,
-               DIR *dirp,
-               SMB_STRUCT_STAT *sbuf)
+                                struct files_struct *dirfsp,
+                                DIR *dirp,
+                                SMB_STRUCT_STAT *sbuf)
 {
        mh_dirinfo_struct* dirInfo = (mh_dirinfo_struct*)dirp;
        struct dirent *d = NULL;
@@ -842,7 +843,7 @@ static struct dirent *mh_readdir(vfs_handle_struct *handle,
 
        if (! dirInfo->isInMediaFiles)
        {
-               d = SMB_VFS_NEXT_READDIR(handle, dirInfo->dirstream, sbuf);
+               d = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirInfo->dirstream, sbuf);
                goto out;
        }
 
@@ -852,7 +853,7 @@ static struct dirent *mh_readdir(vfs_handle_struct *handle,
                bool isAppleDouble;
 
                skip = False;
-               d = SMB_VFS_NEXT_READDIR(handle, dirInfo->dirstream, sbuf);
+               d = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirInfo->dirstream, sbuf);
 
                if (d == NULL)
                {
index 59aaddb163ad2651158938b4beb61efb4fb1aec4..d889dc417b57caffaf554ba919ff8e17341614e9 100644 (file)
@@ -151,7 +151,9 @@ DIR *vfs_not_implemented_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 struct dirent *vfs_not_implemented_readdir(vfs_handle_struct *handle,
-                                          DIR *dirp, SMB_STRUCT_STAT *sbuf)
+                                          struct files_struct *dirfsp,
+                                          DIR *dirp,
+                                          SMB_STRUCT_STAT *sbuf)
 {
        errno = ENOSYS;
        return NULL;
index 79f2097912748b0a01f7e3740b9d7252573fe4d5..37c4657e79b575ac6e812b9b1c6f07c5e4817c48 100644 (file)
@@ -98,7 +98,7 @@ static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
        while (True) {
                struct dirent *d;
 
-               d = SMB_VFS_NEXT_READDIR(handle, p, NULL);
+               d = SMB_VFS_NEXT_READDIR(handle, fsp, p, NULL);
                if (d == NULL) {
                        break;
                }
@@ -126,8 +126,9 @@ static DIR *shadow_copy_fdopendir(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 static struct dirent *shadow_copy_readdir(vfs_handle_struct *handle,
-                                             DIR *_dirp,
-                                             SMB_STRUCT_STAT *sbuf)
+                                         struct files_struct *dirfsp,
+                                         DIR *_dirp,
+                                         SMB_STRUCT_STAT *sbuf)
 {
        shadow_copy_Dir *dirp = (shadow_copy_Dir *)_dirp;
 
index 54577ca887d75f5a2c1f5c26ab7434979daf5cbf..6e4ed60630974410f5e87bf558f02a0897fd8a0b 100644 (file)
@@ -2052,7 +2052,7 @@ static int shadow_copy2_get_shadow_copy_data(
                time(&(priv->snaps->fetch_time));
        }
 
-       while ((d = SMB_VFS_NEXT_READDIR(handle, p, NULL))) {
+       while ((d = SMB_VFS_NEXT_READDIR(handle, dirfsp, p, NULL))) {
                char snapshot[GMT_NAME_LEN+1];
                SHADOW_COPY_LABEL *tlabels;
 
index 7ff0b24ccedb2bd7569f9f06c055a7c8ed18bf29..e18733b55c1be19d70aa5700d5caf61134f10408 100644 (file)
@@ -467,15 +467,16 @@ 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,
+                                            SMB_STRUCT_STAT *sbuf)
 {
        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, sbuf);
        clock_gettime_mono(&ts2);
        timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9;
 
index 014420fd96197ef29c212d288feb23b0969f3dde..72c2e488dd63ae1a8d6613f8e732753094bf104a 100644 (file)
@@ -614,6 +614,7 @@ err:
  * Failure: set errno, return NULL
  */
 static struct dirent *um_readdir(vfs_handle_struct *handle,
+                                struct files_struct *dirfsp,
                                 DIR *dirp,
                                 SMB_STRUCT_STAT *sbuf)
 {
@@ -631,7 +632,7 @@ static struct dirent *um_readdir(vfs_handle_struct *handle,
                   dirInfo->clientSubDirname));
 
        if (!dirInfo->isInMediaFiles) {
-               return SMB_VFS_NEXT_READDIR(handle, dirInfo->dirstream, sbuf);
+               return SMB_VFS_NEXT_READDIR(handle, dirfsp, dirInfo->dirstream, sbuf);
        }
 
        do {
@@ -642,7 +643,7 @@ static struct dirent *um_readdir(vfs_handle_struct *handle,
                uintmax_t number;
 
                skip = false;
-               d = SMB_VFS_NEXT_READDIR(handle, dirInfo->dirstream, sbuf);
+               d = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirInfo->dirstream, sbuf);
 
                if (d == NULL) {
                        break;
index ea3b519eb85a94977e3ee5e8840819325a39e3ca..1cbb0bf0ad03b98bfcc988ad480d0652bd8457a0 100644 (file)
@@ -372,8 +372,9 @@ static int widelinks_openat(vfs_handle_struct *handle,
 }
 
 static struct dirent *widelinks_readdir(vfs_handle_struct *handle,
-                       DIR *dirp,
-                       SMB_STRUCT_STAT *sbuf)
+                                       struct files_struct *dirfsp,
+                                       DIR *dirp,
+                                       SMB_STRUCT_STAT *sbuf)
 {
        struct widelinks_config *config = NULL;
        struct dirent *result;
@@ -384,8 +385,9 @@ static struct dirent *widelinks_readdir(vfs_handle_struct *handle,
                                return NULL);
 
        result = SMB_VFS_NEXT_READDIR(handle,
-                               dirp,
-                               sbuf);
+                                     dirfsp,
+                                     dirp,
+                                     sbuf);
 
        if (!config->active) {
                /* Module not active. */
index 6f70e192daebe955c1f9ea6e3e115a7e14244e44..181a59aa61e35a4a8797fb745aea3e6427559a89 100644 (file)
@@ -1490,7 +1490,7 @@ const char *ReadDirName(struct smb_Dir *dir_hnd, long *poffset,
        /* A real offset, seek to it. */
        SeekDir(dir_hnd, *poffset);
 
-       while ((n = vfs_readdirname(conn, dir_hnd->dir, sbuf, &talloced))) {
+       while ((n = vfs_readdirname(conn, dir_hnd->fsp, dir_hnd->dir, sbuf, &talloced))) {
                /* Ignore . and .. - we've already returned them. */
                if (*n == '.') {
                        if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
index 6192e22fda6c63f199e8d3c4977734d0612c998d..ea81f7a7dd824f44a7187f150d6cfead9d6d329c 100644 (file)
@@ -1287,8 +1287,11 @@ int vfs_slow_fallocate(files_struct *fsp, off_t offset, off_t len);
 int vfs_fill_sparse(files_struct *fsp, off_t len);
 int vfs_set_blocking(files_struct *fsp, bool set);
 off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n);
-const char *vfs_readdirname(connection_struct *conn, void *p,
-                           SMB_STRUCT_STAT *sbuf, char **talloced);
+const char *vfs_readdirname(connection_struct *conn,
+                           struct files_struct *dirfsp,
+                           void *p,
+                           SMB_STRUCT_STAT *sbuf,
+                           char **talloced);
 int vfs_ChDir(connection_struct *conn,
                        const struct smb_filename *smb_fname);
 struct smb_filename *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
index 45e1b9989bcbab62fee67fc1e18e2dd5de3fee59..fd6b15f206c573d4ab46297883b4b5fa227faba2 100644 (file)
@@ -842,8 +842,11 @@ off_t vfs_transfer_file(files_struct *in, files_struct *out, off_t n)
  A vfs_readdir wrapper which just returns the file name.
 ********************************************************************/
 
-const char *vfs_readdirname(connection_struct *conn, void *p,
-                           SMB_STRUCT_STAT *sbuf, char **talloced)
+const char *vfs_readdirname(connection_struct *conn,
+                           struct files_struct *dirfsp,
+                           void *p,
+                           SMB_STRUCT_STAT *sbuf,
+                           char **talloced)
 {
        struct dirent *ptr= NULL;
        const char *dname;
@@ -853,7 +856,7 @@ const char *vfs_readdirname(connection_struct *conn, void *p,
        if (!p)
                return(NULL);
 
-       ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
+       ptr = SMB_VFS_READDIR(conn, dirfsp, (DIR *)p, sbuf);
        if (!ptr)
                return(NULL);
 
@@ -1759,11 +1762,12 @@ DIR *smb_vfs_call_fdopendir(struct vfs_handle_struct *handle,
 }
 
 struct dirent *smb_vfs_call_readdir(struct vfs_handle_struct *handle,
-                                             DIR *dirp,
-                                             SMB_STRUCT_STAT *sbuf)
+                                   struct files_struct *dirfsp,
+                                   DIR *dirp,
+                                   SMB_STRUCT_STAT *sbuf)
 {
        VFS_FIND(readdir);
-       return handle->fns->readdir_fn(handle, dirp, sbuf);
+       return handle->fns->readdir_fn(handle, dirfsp, dirp, sbuf);
 }
 
 void smb_vfs_call_seekdir(struct vfs_handle_struct *handle,