r8535: no longer rely on seekdir working after a closedir. Instead, keep
authorAndrew Tridgell <tridge@samba.org>
Mon, 18 Jul 2005 03:35:52 +0000 (03:35 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:29:36 +0000 (13:29 -0500)
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)

source4/ntvfs/posix/pvfs_dirlist.c
source4/ntvfs/posix/pvfs_search.c
source4/ntvfs/posix/vfs_posix.c
source4/ntvfs/posix/vfs_posix.h

index 1b60f174626ee64668aa919fab46b862b0e040c0..328d07f71b7871fb7698d91fb98baa243aaa691e 100644 (file)
@@ -194,58 +194,16 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs)
 
                if (e->name) talloc_free(e->name);
 
 
                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;
                e->offset = dir->offset;
 
                return e->name;
        }
 
        dir->end_of_search = True;
-       pvfs_list_hibernate(dir);
        return NULL;
 }
 
        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
 */
 /*
   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 pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs)
 {
        struct dirent *de;
-       NTSTATUS status;
        int i;
 
        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) {
        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;
 
 
        dir->end_of_search = True;
 
-       pvfs_list_hibernate(dir);
-
        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 }
        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 }
index 69ca6ef997018e6095dc1fe3b148be57e65f1690..db197c7b621b9c01cc25751e734d6c6dd1ba396c 100644 (file)
@@ -24,6 +24,8 @@
 #include "vfs_posix.h"
 #include "system/time.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #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() */
 
 
 /* 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;
        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;
 }
 
        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
 */
 /*
   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);
        }
 
                talloc_free(file);
        }
 
-       pvfs_list_hibernate(dir);
+       pvfs_search_setup_timer(search);
 
        return NT_STATUS_OK;
 }
 
        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->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);
 
 
        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;
 
        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)) {
        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->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);
 
 
        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;
        }
 
                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;
 
        search->num_ea_names = io->t2fnext.in.num_names;
        search->ea_names = io->t2fnext.in.ea_names;
 
index ac12f3853fbed67566fa3a770dd0deafab7f3b8e..a4b15e3c57de088c522667aaba26159a66aa1f8c 100644 (file)
@@ -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->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
 #if HAVE_XATTR_SUPPORT
        if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE;
 #endif
index b5b0e2b28dd6544321cbfcbd54c68168544ac32b..f18864197d534192d4168b355f1db0ea81a90eff 100644 (file)
@@ -74,6 +74,9 @@ struct pvfs_state {
 
        /* the allocation size rounding */
        uint32_t alloc_size_rounding;
 
        /* 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 {
        
        /* used to accelerate acl mapping */
        struct {