summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Boehme <slow@samba.org>2020-11-22 13:57:27 +0100
committerRalph Boehme <slow@samba.org>2020-12-16 09:08:31 +0000
commitdba8593c6f8c11d18ddc01e54f90c50c44070257 (patch)
tree310e8930d3b9f52abe7c98d073548fb97f4bdf20
parent985c1be5ccf40d0f5c85f42bc0d9bd0a15a86b59 (diff)
downloadsamba-dba8593c6f8c11d18ddc01e54f90c50c44070257.tar.gz
vfs: Add dirfsp arg to SMB_VFS_READDIR()
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>
-rw-r--r--examples/VFS/skel_opaque.c4
-rw-r--r--examples/VFS/skel_transparent.c6
-rw-r--r--source3/include/vfs.h15
-rw-r--r--source3/include/vfs_macros.h8
-rw-r--r--source3/modules/vfs_cap.c7
-rw-r--r--source3/modules/vfs_ceph.c1
-rw-r--r--source3/modules/vfs_default.c5
-rw-r--r--source3/modules/vfs_dirsort.c15
-rw-r--r--source3/modules/vfs_full_audit.c6
-rw-r--r--source3/modules/vfs_glusterfs.c4
-rw-r--r--source3/modules/vfs_media_harmony.c9
-rw-r--r--source3/modules/vfs_not_implemented.c4
-rw-r--r--source3/modules/vfs_shadow_copy.c7
-rw-r--r--source3/modules/vfs_shadow_copy2.c2
-rw-r--r--source3/modules/vfs_time_audit.c7
-rw-r--r--source3/modules/vfs_unityed_media.c5
-rw-r--r--source3/modules/vfs_widelinks.c10
-rw-r--r--source3/smbd/dir.c2
-rw-r--r--source3/smbd/proto.h7
-rw-r--r--source3/smbd/vfs.c16
20 files changed, 89 insertions, 51 deletions
diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c
index 2a3a7301bdb..b74f7360dde 100644
--- a/examples/VFS/skel_opaque.c
+++ b/examples/VFS/skel_opaque.c
@@ -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;
}
diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c
index a86b3e7cd19..969f0572cf5 100644
--- a/examples/VFS/skel_transparent.c
+++ b/examples/VFS/skel_transparent.c
@@ -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)
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index ce971de8627..3110cbd9fe8 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -337,6 +337,7 @@
* 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);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 70d9ab6784c..f3ffe8566c7 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -111,10 +111,10 @@
#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))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index 5deb7754f02..c40d2a25b76 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -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;
}
diff --git a/source3/modules/vfs_ceph.c b/source3/modules/vfs_ceph.c
index 502b72359b3..4c380c3ad20 100644
--- a/source3/modules/vfs_ceph.c
+++ b/source3/modules/vfs_ceph.c
@@ -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)
{
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 21075d725a9..929c4ce7d0e 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -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;
diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c
index 3b3d609563d..d9cfcadacf8 100644
--- a/source3/modules/vfs_dirsort.c
+++ b/source3/modules/vfs_dirsort.c
@@ -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;
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index f1823e3b22e..5a73562a09a 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -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.
diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c
index e4c12931938..b5896feefbd 100644
--- a/source3/modules/vfs_glusterfs.c
+++ b/source3/modules/vfs_glusterfs.c
@@ -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;
diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c
index 12e7ad61806..79fc595339e 100644
--- a/source3/modules/vfs_media_harmony.c
+++ b/source3/modules/vfs_media_harmony.c
@@ -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)
{
diff --git a/source3/modules/vfs_not_implemented.c b/source3/modules/vfs_not_implemented.c
index 59aaddb163a..d889dc417b5 100644
--- a/source3/modules/vfs_not_implemented.c
+++ b/source3/modules/vfs_not_implemented.c
@@ -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;
diff --git a/source3/modules/vfs_shadow_copy.c b/source3/modules/vfs_shadow_copy.c
index 79f20979127..37c4657e79b 100644
--- a/source3/modules/vfs_shadow_copy.c
+++ b/source3/modules/vfs_shadow_copy.c
@@ -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;
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 54577ca887d..6e4ed606309 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -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;
diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c
index 7ff0b24cced..e18733b55c1 100644
--- a/source3/modules/vfs_time_audit.c
+++ b/source3/modules/vfs_time_audit.c
@@ -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;
diff --git a/source3/modules/vfs_unityed_media.c b/source3/modules/vfs_unityed_media.c
index 014420fd961..72c2e488dd6 100644
--- a/source3/modules/vfs_unityed_media.c
+++ b/source3/modules/vfs_unityed_media.c
@@ -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;
diff --git a/source3/modules/vfs_widelinks.c b/source3/modules/vfs_widelinks.c
index ea3b519eb85..1cbb0bf0ad0 100644
--- a/source3/modules/vfs_widelinks.c
+++ b/source3/modules/vfs_widelinks.c
@@ -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. */
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 6f70e192dae..181a59aa61e 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -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')) {
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 6192e22fda6..ea81f7a7dd8 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -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);
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 45e1b9989bc..fd6b15f206c 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -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,