1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

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 commit is contained in:
Andrew Tridgell 2005-07-18 03:35:52 +00:00 committed by Gerald (Jerry) Carter
parent 3dd6e20566
commit 2e8d154e7d
4 changed files with 35 additions and 62 deletions

View File

@ -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;
}

View File

@ -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;

View 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->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

View File

@ -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 {