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:
parent
3dd6e20566
commit
2e8d154e7d
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user