From: Andrew Tridgell Date: Mon, 18 Jul 2005 03:35:52 +0000 (+0000) Subject: r8535: no longer rely on seekdir working after a closedir. Instead, keep X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=b37e82567d28626d39ce02c392d09a815cce497f;p=metze%2Fsamba%2Fwip.git r8535: no longer rely on seekdir working after a closedir. Instead, keep directories open, but close search states based on an inactivity timer, with a default of a 5 minute timeout (This used to be commit 2e8d154e7dfb9b320a1344e957a39e96e1eefadd) --- diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 1b60f174626e..328d07f71b78 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -194,58 +194,16 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) if (e->name) talloc_free(e->name); - e->name = talloc_strdup(dir, de->d_name); + e->name = talloc_strdup(dir->name_cache, de->d_name); e->offset = dir->offset; return e->name; } dir->end_of_search = True; - pvfs_list_hibernate(dir); return NULL; } -/* - put the directory to sleep. Used between search calls to give the - right directory change semantics -*/ -void pvfs_list_hibernate(struct pvfs_dir *dir) -{ - if (dir->dir) { - closedir(dir->dir); - dir->dir = NULL; - } -} - - -/* - wake up the directory search -*/ -NTSTATUS pvfs_list_wakeup(struct pvfs_dir *dir, uint_t *ofs) -{ - if (dir->no_wildcard || - dir->dir != NULL) { - return NT_STATUS_OK; - } - - dir->dir = opendir(dir->unix_path); - if (dir->dir == NULL) { - dir->end_of_search = True; - return pvfs_map_errno(dir->pvfs, errno); - } - - seekdir(dir->dir, *ofs); - dir->offset = telldir(dir->dir); - if (dir->offset != *ofs) { - DEBUG(0,("pvfs_list_wakeup: search offset changed %u -> %u\n", - *ofs, (unsigned)dir->offset)); - } - - return NT_STATUS_OK; -} - - - /* return unix directory of an open search */ @@ -268,14 +226,8 @@ BOOL pvfs_list_eos(struct pvfs_dir *dir, uint_t ofs) NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) { struct dirent *de; - NTSTATUS status; int i; - status = pvfs_list_wakeup(dir, ofs); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - for (i=dir->name_cache_index;i>=0;i--) { struct name_cache_entry *e = &dir->name_cache[i]; if (e->name && StrCaseCmp(name, e->name) == 0) { @@ -303,7 +255,5 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) dir->end_of_search = True; - pvfs_list_hibernate(dir); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 69ca6ef99701..db197c7b621b 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -24,6 +24,8 @@ #include "vfs_posix.h" #include "system/time.h" #include "librpc/gen_ndr/ndr_security.h" +#include "smbd/service_stream.h" +#include "lib/events/events.h" /* the state of a search started with pvfs_search_first() */ @@ -37,6 +39,7 @@ struct pvfs_search_state { time_t last_used; uint_t num_ea_names; struct ea_name *ea_names; + struct timed_event *te; }; @@ -54,6 +57,28 @@ static int pvfs_search_destructor(void *ptr) return 0; } +/* + called when a search timer goes off +*/ +static void pvfs_search_timer(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct pvfs_search_state *search = talloc_get_type(ptr, struct pvfs_search_state); + talloc_free(search); +} + +/* + setup a timer to destroy a open search after a inactivity period +*/ +static void pvfs_search_setup_timer(struct pvfs_search_state *search) +{ + struct event_context *ev = search->pvfs->tcon->smb_conn->connection->event.ctx; + talloc_free(search->te); + search->te = event_add_timed(ev, search, + timeval_current_ofs(search->pvfs->search_inactivity_time, 0), + pvfs_search_timer, search); +} + /* fill in a single search result for a given info level */ @@ -266,7 +291,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, talloc_free(file); } - pvfs_list_hibernate(dir); + pvfs_search_setup_timer(search); return NT_STATUS_OK; } @@ -362,6 +387,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, search->search_attrib = search_attrib & 0xFF; search->must_attrib = (search_attrib>>8) & 0xFF; search->last_used = time(NULL); + search->te = NULL; talloc_set_destructor(search, pvfs_search_destructor); @@ -409,11 +435,6 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, search->last_used = time(NULL); dir = search->dir; - status = pvfs_list_wakeup(dir, &search->current_index); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -499,6 +520,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, search->last_used = 0; search->num_ea_names = io->t2ffirst.in.num_names; search->ea_names = io->t2ffirst.in.ea_names; + search->te = NULL; talloc_set_destructor(search, pvfs_search_destructor); @@ -573,11 +595,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, search->current_index = io->t2fnext.in.resume_key; } - status = pvfs_list_wakeup(dir, &search->current_index); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - search->num_ea_names = io->t2fnext.in.num_names; search->ea_names = io->t2fnext.in.ea_names; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ac12f3853fbe..a4b15e3c57de 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -55,6 +55,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->alloc_size_rounding = lp_parm_int(snum, "posix", "allocationrounding", 512); + pvfs->search_inactivity_time = lp_parm_int(snum, + "posix", "searchinactivity", 300); + #if HAVE_XATTR_SUPPORT if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index b5b0e2b28dd6..f18864197d53 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -74,6 +74,9 @@ struct pvfs_state { /* the allocation size rounding */ uint32_t alloc_size_rounding; + + /* how long to keep inactive searches around for */ + uint_t search_inactivity_time; /* used to accelerate acl mapping */ struct {