1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

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
This commit is contained in:
Steven Danneman 2009-01-22 20:14:38 -08:00
parent 9a7491e831
commit af0e199b31
12 changed files with 63 additions and 21 deletions

View File

@ -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);

View File

@ -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))

View File

@ -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))

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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;
}