diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/param/loadparm.c | 9 | ||||
-rw-r--r-- | source3/smbd/dir.c | 53 |
2 files changed, 41 insertions, 21 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 45d2f87913..7e573052e1 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -471,6 +471,7 @@ typedef struct { int iAioReadSize; int iAioWriteSize; int iMap_readonly; + int iDirectoryNameCacheSize; param_opt_struct *param_opt; char dummy[3]; /* for alignment */ @@ -611,7 +612,11 @@ static service sDefault = { 0, /* iAioReadSize */ 0, /* iAioWriteSize */ MAP_READONLY_YES, /* iMap_readonly */ - +#ifdef BROKEN_DIRECTORY_HANDLING + 0, /* iDirectoryNameCacheSize */ +#else + 100, /* iDirectoryNameCacheSize */ +#endif NULL, /* Parametric options */ "" /* dummy */ @@ -1031,6 +1036,7 @@ static struct parm_struct parm_table[] = { {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, FLAG_ADVANCED}, {"keepalive", P_INTEGER, P_GLOBAL, &Globals.iKeepalive, NULL, NULL, FLAG_ADVANCED}, {"change notify", P_BOOL, P_LOCAL, &sDefault.bChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, + {"directory name cache size", P_INTEGER, P_LOCAL, &sDefault.iDirectoryNameCacheSize, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, {"kernel change notify", P_BOOL, P_LOCAL, &sDefault.bKernelChangeNotify, NULL, NULL, FLAG_ADVANCED | FLAG_SHARE }, {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, FLAG_ADVANCED}, @@ -2178,6 +2184,7 @@ FN_LOCAL_INTEGER(lp_allocation_roundup_size, iallocation_roundup_size) FN_LOCAL_INTEGER(lp_aio_read_size, iAioReadSize) FN_LOCAL_INTEGER(lp_aio_write_size, iAioWriteSize) FN_LOCAL_INTEGER(lp_map_readonly, iMap_readonly) +FN_LOCAL_INTEGER(lp_directory_name_cache_size, iDirectoryNameCacheSize) FN_LOCAL_CHAR(lp_magicchar, magic_char) FN_GLOBAL_INTEGER(lp_winbind_cache_time, &Globals.winbind_cache_time) FN_GLOBAL_LIST(lp_winbind_nss_info, &Globals.szWinbindNssInfo) diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 30c1d77a84..eec8fa12ef 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -32,8 +32,6 @@ extern struct current_user current_user; /* Make directory handle internals available. */ -#define NAME_CACHE_SIZE 100 - struct name_cache_entry { char *name; long offset; @@ -44,6 +42,7 @@ struct smb_Dir { SMB_STRUCT_DIR *dir; long offset; char *dir_path; + size_t name_cache_size; struct name_cache_entry *name_cache; unsigned int name_cache_index; unsigned int file_number; @@ -1061,12 +1060,14 @@ BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char * struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *mask, uint32 attr) { struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir); + if (!dirp) { return NULL; } ZERO_STRUCTP(dirp); dirp->conn = conn; + dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); dirp->dir_path = SMB_STRDUP(name); if (!dirp->dir_path) { @@ -1078,9 +1079,14 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, const char *m goto fail; } - dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, NAME_CACHE_SIZE); - if (!dirp->name_cache) { - goto fail; + if (dirp->name_cache_size) { + dirp->name_cache = SMB_CALLOC_ARRAY(struct name_cache_entry, + dirp->name_cache_size); + if (!dirp->name_cache) { + goto fail; + } + } else { + dirp->name_cache = NULL; } dirhandles_open++; @@ -1113,7 +1119,7 @@ int CloseDir(struct smb_Dir *dirp) } SAFE_FREE(dirp->dir_path); if (dirp->name_cache) { - for (i = 0; i < NAME_CACHE_SIZE; i++) { + for (i = 0; i < dirp->name_cache_size; i++) { SAFE_FREE(dirp->name_cache[i].name); } } @@ -1229,7 +1235,12 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, long offset) { struct name_cache_entry *e; - dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE; + if (!dirp->name_cache_size || !dirp->name_cache) { + return; + } + + dirp->name_cache_index = (dirp->name_cache_index+1) % + dirp->name_cache_size; e = &dirp->name_cache[dirp->name_cache_index]; SAFE_FREE(e->name); e->name = SMB_STRDUP(name); @@ -1248,20 +1259,22 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset) connection_struct *conn = dirp->conn; /* Search back in the name cache. */ - for (i = dirp->name_cache_index; i >= 0; i--) { - struct name_cache_entry *e = &dirp->name_cache[i]; - if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { - *poffset = e->offset; - SeekDir(dirp, e->offset); - return True; + if (dirp->name_cache_size && dirp->name_cache) { + for (i = dirp->name_cache_index; i >= 0; i--) { + struct name_cache_entry *e = &dirp->name_cache[i]; + if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + *poffset = e->offset; + SeekDir(dirp, e->offset); + return True; + } } - } - for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) { - struct name_cache_entry *e = &dirp->name_cache[i]; - if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { - *poffset = e->offset; - SeekDir(dirp, e->offset); - return True; + for (i = dirp->name_cache_size - 1; i > dirp->name_cache_index; i--) { + struct name_cache_entry *e = &dirp->name_cache[i]; + if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) { + *poffset = e->offset; + SeekDir(dirp, e->offset); + return True; + } } } |