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:
parent
9a7491e831
commit
af0e199b31
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user