summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorSteven Danneman <steven.danneman@isilon.com>2009-01-22 20:14:38 -0800
committerSteven Danneman <steven.danneman@isilon.com>2009-02-09 23:56:16 -0800
commitaf0e199b31ea4132e369508d72888757887b3327 (patch)
tree38be76f86b5c7b226785ed8c5cec559fab775756 /source3
parent9a7491e83177ba32e30f29e1b84b8b8be9888953 (diff)
downloadsamba-af0e199b31ea4132e369508d72888757887b3327.tar.gz
samba-af0e199b31ea4132e369508d72888757887b3327.tar.bz2
samba-af0e199b31ea4132e369508d72888757887b3327.zip
Add an optional SMB_STRUCT_SMB parameter to VFS_OP_READDIR
* this allows VFS implementations that prefetch stat information on readdir to return it through one VFS call * backwards compatibility is maintained by passing in NULL * if the system readdir doesn't return stat info, the stat struct is set to invalid
Diffstat (limited to 'source3')
-rw-r--r--source3/include/vfs.h5
-rw-r--r--source3/include/vfs_macros.h8
-rw-r--r--source3/modules/onefs_streams.c2
-rw-r--r--source3/modules/vfs_cap.c2
-rw-r--r--source3/modules/vfs_catia.c5
-rw-r--r--source3/modules/vfs_default.c8
-rw-r--r--source3/modules/vfs_full_audit.c7
-rw-r--r--source3/modules/vfs_shadow_copy.c4
-rw-r--r--source3/modules/vfs_shadow_copy2.c2
-rw-r--r--source3/modules/vfs_streams_depot.c2
-rw-r--r--source3/smbd/vfs.c4
-rw-r--r--source3/torture/cmd_vfs.c35
12 files changed, 63 insertions, 21 deletions
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index 228f090600..6aea0ae6a0 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -113,6 +113,7 @@
/* Leave at 25 - not yet released. Add create_file call. -- tprouty. */
/* Leave at 25 - not yet released. Add create time to ntimes. -- tstecher. */
/* Leave at 25 - not yet released. Add get_alloc_size call. -- tprouty. */
+/* Leave at 25 - not yet released. Add SMB_STRUCT_STAT to readdir. - sdann */
#define SMB_VFS_INTERFACE_VERSION 25
@@ -303,7 +304,9 @@ struct vfs_ops {
/* Directory operations */
SMB_STRUCT_DIR *(*opendir)(struct vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attributes);
- SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp);
+ SMB_STRUCT_DIRENT *(*readdir)(struct vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf);
void (*seekdir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, long offset);
long (*telldir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp);
void (*rewind_dir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp);
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index e7a9cfdc76..208566f77e 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -38,7 +38,7 @@
/* Directory operations */
#define SMB_VFS_OPENDIR(conn, fname, mask, attr) ((conn)->vfs.ops.opendir((conn)->vfs.handles.opendir, (fname), (mask), (attr)))
-#define SMB_VFS_READDIR(conn, dirp) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (dirp)))
+#define SMB_VFS_READDIR(conn, dirp, sbuf) ((conn)->vfs.ops.readdir((conn)->vfs.handles.readdir, (dirp), (sbuf)))
#define SMB_VFS_SEEKDIR(conn, dirp, offset) ((conn)->vfs.ops.seekdir((conn)->vfs.handles.seekdir, (dirp), (offset)))
#define SMB_VFS_TELLDIR(conn, dirp) ((conn)->vfs.ops.telldir((conn)->vfs.handles.telldir, (dirp)))
#define SMB_VFS_REWINDDIR(conn, dirp) ((conn)->vfs.ops.rewind_dir((conn)->vfs.handles.rewind_dir, (dirp)))
@@ -166,7 +166,7 @@
/* Directory operations */
#define SMB_VFS_OPAQUE_OPENDIR(conn, fname, mask, attr) ((conn)->vfs_opaque.ops.opendir((conn)->vfs_opaque.handles.opendir, (fname), (mask), (attr)))
-#define SMB_VFS_OPAQUE_READDIR(conn, dirp) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (dirp)))
+#define SMB_VFS_OPAQUE_READDIR(conn, dirp, sbuf) ((conn)->vfs_opaque.ops.readdir((conn)->vfs_opaque.handles.readdir, (dirp), (sbuf)))
#define SMB_VFS_OPAQUE_SEEKDIR(conn, dirp, offset) ((conn)->vfs_opaque.ops.seekdir((conn)->vfs_opaque.handles.seekdir, (dirp), (offset)))
#define SMB_VFS_OPAQUE_TELLDIR(conn, dirp) ((conn)->vfs_opaque.ops.telldir((conn)->vfs_opaque.handles.telldir, (dirp)))
#define SMB_VFS_OPAQUE_REWINDDIR(conn, dirp) ((conn)->vfs_opaque.ops.rewind_dir((conn)->vfs_opaque.handles.rewind_dir, (dirp)))
@@ -294,11 +294,11 @@
/* Directory operations */
#define SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr) ((handle)->vfs_next.ops.opendir((handle)->vfs_next.handles.opendir, (fname), (mask), (attr)))
-#define SMB_VFS_NEXT_READDIR(handle, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp)))
+#define SMB_VFS_NEXT_READDIR(handle, dirp, sbuf) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp), (sbuf)))
#define SMB_VFS_NEXT_SEEKDIR(handle, dirp, offset) ((handle)->vfs_next.ops.seekdir((handle)->vfs_next.handles.seekdir, (dirp), (offset)))
#define SMB_VFS_NEXT_TELLDIR(handle, dirp) ((handle)->vfs_next.ops.telldir((handle)->vfs_next.handles.telldir, (dirp)))
#define SMB_VFS_NEXT_REWINDDIR(handle, dirp) ((handle)->vfs_next.ops.rewind_dir((handle)->vfs_next.handles.rewind_dir, (dirp)))
-#define SMB_VFS_NEXT_DIR(handle, dirp) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp)))
+#define SMB_VFS_NEXT_DIR(handle, dirp, sbuf) ((handle)->vfs_next.ops.readdir((handle)->vfs_next.handles.readdir, (dirp), (sbuf)))
#define SMB_VFS_NEXT_MKDIR(handle, path, mode) ((handle)->vfs_next.ops.mkdir((handle)->vfs_next.handles.mkdir,(path), (mode)))
#define SMB_VFS_NEXT_RMDIR(handle, path) ((handle)->vfs_next.ops.rmdir((handle)->vfs_next.handles.rmdir, (path)))
#define SMB_VFS_NEXT_CLOSEDIR(handle, dir) ((handle)->vfs_next.ops.closedir((handle)->vfs_next.handles.closedir, dir))
diff --git a/source3/modules/onefs_streams.c b/source3/modules/onefs_streams.c
index 615edf379d..d0dd75f259 100644
--- a/source3/modules/onefs_streams.c
+++ b/source3/modules/onefs_streams.c
@@ -545,7 +545,7 @@ static NTSTATUS walk_onefs_streams(connection_struct *conn, files_struct *fsp,
fake_fs.fsp_name = SMB_STRDUP(fname);
/* Iterate over the streams in the ADS directory. */
- while ((dp = SMB_VFS_READDIR(conn, dirp)) != NULL) {
+ while ((dp = SMB_VFS_READDIR(conn, dirp, NULL)) != NULL) {
/* Skip the "." and ".." entries */
if ((strcmp(dp->d_name, ".") == 0) ||
(strcmp(dp->d_name, "..") == 0))
diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c
index ac85d3a804..e26d29d667 100644
--- a/source3/modules/vfs_cap.c
+++ b/source3/modules/vfs_cap.c
@@ -61,7 +61,7 @@ static SMB_STRUCT_DIRENT *cap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR
size_t newnamelen;
DEBUG(3,("cap: cap_readdir\n"));
- result = SMB_VFS_NEXT_READDIR(handle, dirp);
+ result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
if (!result) {
return NULL;
}
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index d0c341fdd3..2870254bfb 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -105,11 +105,12 @@ static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct *handle,
static SMB_STRUCT_DIRENT *catia_readdir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp)
{
- SMB_STRUCT_DIRENT *result = SMB_VFS_NEXT_READDIR(handle, dirp);
- SMB_STRUCT_DIRENT *newdirent;
+ SMB_STRUCT_DIRENT *result = NULL;
+ SMB_STRUCT_DIRENT *newdirent = NULL;
char *newname;
size_t newnamelen;
+ result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
if (result == NULL) {
return result;
}
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 679be57558..7d61191a69 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -113,12 +113,18 @@ static SMB_STRUCT_DIR *vfswrap_opendir(vfs_handle_struct *handle, const char *f
return result;
}
-static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp)
+static SMB_STRUCT_DIRENT *vfswrap_readdir(vfs_handle_struct *handle,
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result;
START_PROFILE(syscall_readdir);
result = sys_readdir(dirp);
+ /* Default Posix readdir() does not give us stat info.
+ * Set to invalid to indicate we didn't return this info. */
+ if (sbuf)
+ SET_STAT_INVALID(*sbuf);
END_PROFILE(syscall_readdir);
return result;
}
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index c6d62fdd87..e279772494 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -94,7 +94,8 @@ static int smb_full_audit_statvfs(struct vfs_handle_struct *handle,
static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle,
const char *fname, const char *mask, uint32 attr);
static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
- SMB_STRUCT_DIR *dirp);
+ SMB_STRUCT_DIR *dirp,
+ SMB_STRUCT_STAT *sbuf);
static void smb_full_audit_seekdir(vfs_handle_struct *handle,
SMB_STRUCT_DIR *dirp, long offset);
static long smb_full_audit_telldir(vfs_handle_struct *handle,
@@ -1029,11 +1030,11 @@ static SMB_STRUCT_DIR *smb_full_audit_opendir(vfs_handle_struct *handle,
}
static SMB_STRUCT_DIRENT *smb_full_audit_readdir(vfs_handle_struct *handle,
- SMB_STRUCT_DIR *dirp)
+ SMB_STRUCT_DIR *dirp, SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *result;
- result = SMB_VFS_NEXT_READDIR(handle, dirp);
+ result = SMB_VFS_NEXT_READDIR(handle, dirp, sbuf);
/* This operation has no reasonable error condition
* (End of dir is also failure), so always succeed.
diff --git a/source3/modules/vfs_shadow_copy.c b/source3/modules/vfs_shadow_copy.c
index fbd2960aba..4f5cedb3d4 100644
--- a/source3/modules/vfs_shadow_copy.c
+++ b/source3/modules/vfs_shadow_copy.c
@@ -93,7 +93,7 @@ static SMB_STRUCT_DIR *shadow_copy_opendir(vfs_handle_struct *handle, const char
while (True) {
SMB_STRUCT_DIRENT *d;
- d = SMB_VFS_NEXT_READDIR(handle, p);
+ d = SMB_VFS_NEXT_READDIR(handle, p, NULL);
if (d == NULL) {
break;
}
@@ -176,7 +176,7 @@ static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_str
SHADOW_COPY_LABEL *tlabels;
SMB_STRUCT_DIRENT *d;
- d = SMB_VFS_NEXT_READDIR(handle, p);
+ d = SMB_VFS_NEXT_READDIR(handle, p, NULL);
if (d == NULL) {
break;
}
diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c
index 56dd6ea8d8..9eaf8ee851 100644
--- a/source3/modules/vfs_shadow_copy2.c
+++ b/source3/modules/vfs_shadow_copy2.c
@@ -524,7 +524,7 @@ static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
shadow_copy2_data->num_volumes = 0;
shadow_copy2_data->labels = NULL;
- while ((d = SMB_VFS_NEXT_READDIR(handle, p))) {
+ while ((d = SMB_VFS_NEXT_READDIR(handle, p, NULL))) {
SHADOW_COPY_LABEL *tlabels;
/* ignore names not of the right form in the snapshot directory */
diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c
index 77efb277de..1c2c0e5f77 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -352,7 +352,7 @@ static NTSTATUS walk_streams(vfs_handle_struct *handle,
return map_nt_error_from_unix(errno);
}
- while ((dirent = vfs_readdirname(handle->conn, dirhandle)) != NULL) {
+ while ((dirent = vfs_readdirname(handle->conn, dirhandle, NULL)) != NULL) {
if (ISDOT(dirent) || ISDOTDOT(dirent)) {
continue;
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c
index 8d82ca550c..9580247368 100644
--- a/source3/smbd/vfs.c
+++ b/source3/smbd/vfs.c
@@ -705,7 +705,7 @@ SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n)
A vfs_readdir wrapper which just returns the file name.
********************************************************************/
-char *vfs_readdirname(connection_struct *conn, void *p)
+char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf)
{
SMB_STRUCT_DIRENT *ptr= NULL;
char *dname;
@@ -713,7 +713,7 @@ char *vfs_readdirname(connection_struct *conn, void *p)
if (!p)
return(NULL);
- ptr = SMB_VFS_READDIR(conn, (DIR *)p);
+ ptr = SMB_VFS_READDIR(conn, (DIR *)p, sbuf);
if (!ptr)
return(NULL);
diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c
index 31eb27b756..f273cedb90 100644
--- a/source3/torture/cmd_vfs.c
+++ b/source3/torture/cmd_vfs.c
@@ -141,20 +141,51 @@ static NTSTATUS cmd_opendir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc
static NTSTATUS cmd_readdir(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int argc, const char **argv)
{
- SMB_STRUCT_DIRENT *dent;
+ const char *user;
+ const char *group;
+ SMB_STRUCT_STAT st;
+ SMB_STRUCT_DIRENT *dent = NULL;
if (vfs->currentdir == NULL) {
printf("readdir: error=-1 (no open directory)\n");
return NT_STATUS_UNSUCCESSFUL;
}
- dent = SMB_VFS_READDIR(vfs->conn, vfs->currentdir);
+ dent = SMB_VFS_READDIR(vfs->conn, vfs->currentdir, &st);
if (dent == NULL) {
printf("readdir: NULL\n");
return NT_STATUS_OK;
}
printf("readdir: %s\n", dent->d_name);
+ if (VALID_STAT(st)) {
+ printf(" stat available");
+ if (S_ISREG(st.st_mode)) printf(" Regular File\n");
+ else if (S_ISDIR(st.st_mode)) printf(" Directory\n");
+ else if (S_ISCHR(st.st_mode)) printf(" Character Device\n");
+ else if (S_ISBLK(st.st_mode)) printf(" Block Device\n");
+ else if (S_ISFIFO(st.st_mode)) printf(" Fifo\n");
+ else if (S_ISLNK(st.st_mode)) printf(" Symbolic Link\n");
+ else if (S_ISSOCK(st.st_mode)) printf(" Socket\n");
+ printf(" Size: %10u", (unsigned int)st.st_size);
+#ifdef HAVE_STAT_ST_BLOCKS
+ printf(" Blocks: %9u", (unsigned int)st.st_blocks);
+#endif
+#ifdef HAVE_STAT_ST_BLKSIZE
+ printf(" IO Block: %u\n", (unsigned int)st.st_blksize);
+#endif
+ printf(" Device: 0x%10x", (unsigned int)st.st_dev);
+ printf(" Inode: %10u", (unsigned int)st.st_ino);
+ printf(" Links: %10u\n", (unsigned int)st.st_nlink);
+ printf(" Access: %05o", (st.st_mode) & 007777);
+ printf(" Uid: %5lu/%.16s Gid: %5lu/%.16s\n",
+ (unsigned long)st.st_uid, user,
+ (unsigned long)st.st_gid, group);
+ printf(" Access: %s", ctime(&(st.st_atime)));
+ printf(" Modify: %s", ctime(&(st.st_mtime)));
+ printf(" Change: %s", ctime(&(st.st_ctime)));
+ }
+
return NT_STATUS_OK;
}