summaryrefslogtreecommitdiff
path: root/source4/ntvfs/posix
diff options
context:
space:
mode:
Diffstat (limited to 'source4/ntvfs/posix')
-rw-r--r--source4/ntvfs/posix/pvfs_dirlist.c52
-rw-r--r--source4/ntvfs/posix/pvfs_search.c39
-rw-r--r--source4/ntvfs/posix/vfs_posix.c3
-rw-r--r--source4/ntvfs/posix/vfs_posix.h3
4 files changed, 35 insertions, 62 deletions
diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c
index 1b60f17462..328d07f71b 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 69ca6ef997..db197c7b62 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;
};
@@ -55,6 +58,28 @@ static int pvfs_search_destructor(void *ptr)
}
/*
+ 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
*/
static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
@@ -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 ac12f3853f..a4b15e3c57 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 b5b0e2b28d..f18864197d 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 {