From 6272f4c2f453c509b8a3893d4c2ac5fc356b348d Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Mon, 2 Feb 2009 21:37:51 -0800 Subject: [PATCH] s3: Added SMB_VFS_INIT_SEARCH_OP to initialize data at the beginning of SMB search requests. By default this VFS call is a NOOP, but the onefs vfs module takes advantage of it to initialize direntry search caches at the beginning of each TRANS2_FIND_FIRST, TRANS2_FIND_NEXT, SMBffirst, SMBsearch, and SMBunique --- source3/include/proto.h | 1 + source3/include/vfs.h | 8 ++++++-- source3/include/vfs_macros.h | 3 +++ source3/modules/vfs_default.c | 9 +++++++++ source3/modules/vfs_full_audit.c | 14 ++++++++++++++ source3/smbd/dir.c | 8 ++++++++ source3/smbd/reply.c | 3 +++ source3/smbd/trans2.c | 12 +++++++++--- 8 files changed, 53 insertions(+), 5 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index eef7a0dd247..849bed3b0b8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6495,6 +6495,7 @@ const char *dptr_ReadDirName(TALLOC_CTX *ctx, SMB_STRUCT_STAT *pst); bool dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst); void dptr_DirCacheAdd(struct dptr_struct *dptr, const char *name, long offset); +void dptr_init_search_op(struct dptr_struct *dptr); bool dptr_fill(char *buf1,unsigned int key); struct dptr_struct *dptr_fetch(char *buf,int *num); struct dptr_struct *dptr_fetch_lanman2(int dptr_num); diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 6aea0ae6a08..99af30b1c5e 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -114,6 +114,7 @@ /* 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 */ +/* Leave at 25 - not yet released. Add init_search_op call. - sdann */ #define SMB_VFS_INTERFACE_VERSION 25 @@ -144,14 +145,14 @@ struct smb_file_time; /* Available VFS operations. These values must be in sync with vfs_ops struct - (struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops). + (struct vfs_fn_pointers and struct vfs_handle_pointers inside of struct vfs_ops). In particular, if new operations are added to vfs_ops, appropriate constants should be added to vfs_op_type so that order of them kept same as in vfs_ops. */ typedef enum _vfs_op_type { SMB_VFS_OP_NOOP = -1, - + /* Disk operations */ SMB_VFS_OP_CONNECT = 0, @@ -173,6 +174,7 @@ typedef enum _vfs_op_type { SMB_VFS_OP_MKDIR, SMB_VFS_OP_RMDIR, SMB_VFS_OP_CLOSEDIR, + SMB_VFS_OP_INIT_SEARCH_OP, /* File operations */ @@ -313,6 +315,7 @@ struct vfs_ops { int (*mkdir)(struct vfs_handle_struct *handle, const char *path, mode_t mode); int (*rmdir)(struct vfs_handle_struct *handle, const char *path); int (*closedir)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dir); + void (*init_search_op)(struct vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); /* File operations */ @@ -484,6 +487,7 @@ struct vfs_ops { struct vfs_handle_struct *mkdir; struct vfs_handle_struct *rmdir; struct vfs_handle_struct *closedir; + struct vfs_handle_struct *init_search_op; /* File operations */ diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 208566f77e0..e57cbd25386 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -45,6 +45,7 @@ #define SMB_VFS_MKDIR(conn, path, mode) ((conn)->vfs.ops.mkdir((conn)->vfs.handles.mkdir,(path), (mode))) #define SMB_VFS_RMDIR(conn, path) ((conn)->vfs.ops.rmdir((conn)->vfs.handles.rmdir, (path))) #define SMB_VFS_CLOSEDIR(conn, dir) ((conn)->vfs.ops.closedir((conn)->vfs.handles.closedir, dir)) +#define SMB_VFS_INIT_SEARCH_OP(conn, dirp) ((conn)->vfs.ops.init_search_op((conn)->vfs.handles.init_search_op, (dirp))) /* File operations */ #define SMB_VFS_OPEN(conn, fname, fsp, flags, mode) (((conn)->vfs.ops.open)((conn)->vfs.handles.open, (fname), (fsp), (flags), (mode))) @@ -173,6 +174,7 @@ #define SMB_VFS_OPAQUE_MKDIR(conn, path, mode) ((conn)->vfs_opaque.ops.mkdir((conn)->vfs_opaque.handles.mkdir,(path), (mode))) #define SMB_VFS_OPAQUE_RMDIR(conn, path) ((conn)->vfs_opaque.ops.rmdir((conn)->vfs_opaque.handles.rmdir, (path))) #define SMB_VFS_OPAQUE_CLOSEDIR(conn, dir) ((conn)->vfs_opaque.ops.closedir((conn)->vfs_opaque.handles.closedir, dir)) +#define SMB_VFS_OPAQUE_INIT_SEARCH_OP(conn, dirp) ((conn)->vfs_opaque.ops.init_search_op((conn)->vfs_opaque.handles.init_search_op, (dirp))) /* File operations */ #define SMB_VFS_OPAQUE_OPEN(conn, fname, fsp, flags, mode) (((conn)->vfs_opaque.ops.open)((conn)->vfs_opaque.handles.open, (fname), (fsp), (flags), (mode))) @@ -302,6 +304,7 @@ #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)) +#define SMB_VFS_NEXT_INIT_SEARCH_OP(handle, dirp) ((handle)->vfs_next.ops.init_search_op((handle)->vfs_next.handles.init_search_op, (dirp))) /* File operations */ #define SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode) (((handle)->vfs_next.ops.open)((handle)->vfs_next.handles.open, (fname), (fsp), (flags), (mode))) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 7d61191a697..cb56690dbb8 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -206,6 +206,13 @@ static int vfswrap_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) return result; } +static void vfswrap_init_search_op(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp) +{ + /* Default behavior is a NOOP */ + return; +} + /* File operations */ static int vfswrap_open(vfs_handle_struct *handle, const char *fname, @@ -1449,6 +1456,8 @@ static vfs_op_tuple vfs_default_ops[] = { SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(vfswrap_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfswrap_init_search_op), SMB_VFS_OP_INIT_SEARCH_OP, + SMB_VFS_LAYER_OPAQUE}, /* File operations */ diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e279772494d..e7ca77f6fa9 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -108,6 +108,8 @@ static int smb_full_audit_rmdir(vfs_handle_struct *handle, const char *path); static int smb_full_audit_closedir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp); +static void smb_full_audit_init_search_op(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp); static int smb_full_audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode); static NTSTATUS smb_full_audit_create_file(vfs_handle_struct *handle, @@ -373,6 +375,8 @@ static vfs_op_tuple audit_op_tuples[] = { SMB_VFS_LAYER_LOGGER}, {SMB_VFS_OP(smb_full_audit_closedir), SMB_VFS_OP_CLOSEDIR, SMB_VFS_LAYER_LOGGER}, + {SMB_VFS_OP(smb_full_audit_init_search_op), SMB_VFS_OP_INIT_SEARCH_OP, + SMB_VFS_LAYER_LOGGER}, /* File operations */ @@ -587,6 +591,7 @@ static struct { { SMB_VFS_OP_MKDIR, "mkdir" }, { SMB_VFS_OP_RMDIR, "rmdir" }, { SMB_VFS_OP_CLOSEDIR, "closedir" }, + { SMB_VFS_OP_INIT_SEARCH_OP, "init_search_op" }, { SMB_VFS_OP_OPEN, "open" }, { SMB_VFS_OP_CREATE_FILE, "create_file" }, { SMB_VFS_OP_CLOSE, "close" }, @@ -1110,6 +1115,15 @@ static int smb_full_audit_closedir(vfs_handle_struct *handle, return result; } +static void smb_full_audit_init_search_op(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp) +{ + SMB_VFS_NEXT_INIT_SEARCH_OP(handle, dirp); + + do_log(SMB_VFS_OP_INIT_SEARCH_OP, True, handle, ""); + return; +} + static int smb_full_audit_open(vfs_handle_struct *handle, const char *fname, files_struct *fsp, int flags, mode_t mode) { diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index c4f6b4fe559..6618bf07b01 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -681,6 +681,14 @@ void dptr_DirCacheAdd(struct dptr_struct *dptr, const char *name, long offset) } /**************************************************************************** + Initialize variables & state data at the beginning of all search SMB requests. +****************************************************************************/ +void dptr_init_search_op(struct dptr_struct *dptr) +{ + return SMB_VFS_INIT_SEARCH_OP(dptr->conn, dptr->dir_hnd->dir); +} + +/**************************************************************************** Fill the 5 byte server reserved dptr field. ****************************************************************************/ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 628f481c1ce..256160c4025 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1380,6 +1380,9 @@ void reply_search(struct smb_request *req) DEBUG(4,("dptr_num is %d\n",dptr_num)); + /* Initialize per SMBsearch/SMBffirst/SMBfunique operation data */ + dptr_init_search_op(conn->dirptr); + if ((dirtype&0x1F) == aVOLID) { char buf[DIR_STRUCT_SIZE]; memcpy(buf,status,21); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6a6e59a581a..cea066e97ff 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1914,7 +1914,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n", /* W2K3 seems to treat zero as 1. */ maxentries = 1; } - + switch (info_level) { case SMB_FIND_INFO_STANDARD: case SMB_FIND_EA_SIZE: @@ -2043,7 +2043,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } params = *pparams; - /* Save the wildcard match and attribs we are using on this directory - + /* Save the wildcard match and attribs we are using on this directory - needed as lanman2 assumes these are being saved between calls */ ntstatus = dptr_create(conn, @@ -2064,6 +2064,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd dptr_num = dptr_dnum(conn->dirptr); DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n", dptr_num, mask, dirtype)); + /* Initialize per TRANS2_FIND_FIRST operation data */ + dptr_init_search_op(conn->dirptr); + /* We don't need to check for VOL here as this is returned by a different TRANS2 call. */ @@ -2078,7 +2081,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd for (i=0;(i 0) { out_of_space = True; @@ -2374,6 +2377,9 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd (long)conn->dirptr, dptr_TellDir(conn->dirptr))); + /* Initialize per TRANS2_FIND_NEXT operation data */ + dptr_init_search_op(conn->dirptr); + /* We don't need to check for VOL here as this is returned by a different TRANS2 call. */ -- 2.11.4.GIT