diff --git a/src/stat_cache.c b/src/stat_cache.c index 8b479ecb..1159b0b9 100644 --- a/src/stat_cache.c +++ b/src/stat_cache.c @@ -107,9 +107,9 @@ static uint32_t hashme(const char *str, const size_t len) #include typedef struct { - FAMRequest *req; buffer *name; int version; + FAMRequest req; } fam_dir_entry; typedef struct stat_cache_fam { @@ -119,7 +119,7 @@ typedef struct stat_cache_fam { int dir_ndx; fam_dir_entry *fam_dir; - buffer *dir_name; /* for building the dirname from the filename */ + size_t dirlen; /* for building the dirname from the filename */ fdnode *fdn; int fd; } stat_cache_fam; @@ -140,11 +140,9 @@ static void fam_dir_entry_free(FAMConnection *fc, void *data) { if (!fam_dir) return; - FAMCancelMonitor(fc, fam_dir->req); + FAMCancelMonitor(fc, &fam_dir->req); buffer_free(fam_dir->name); - free(fam_dir->req); - free(fam_dir); } @@ -216,7 +214,6 @@ static handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) static stat_cache_fam * stat_cache_init_fam(server *srv) { stat_cache_fam *scf = calloc(1, sizeof(*scf)); - scf->dir_name = buffer_init(); scf->fd = -1; /* setup FAM */ @@ -239,7 +236,6 @@ static stat_cache_fam * stat_cache_init_fam(server *srv) { static void stat_cache_free_fam(stat_cache_fam *scf) { if (NULL == scf) return; - buffer_free(scf->dir_name); while (scf->dirs) { splay_tree *node = scf->dirs; @@ -256,29 +252,19 @@ static void stat_cache_free_fam(stat_cache_fam *scf) { free(scf); } -static int buffer_copy_dirname(buffer *dst, const buffer *file) { - size_t i; - - if (buffer_string_is_empty(file)) return -1; - - for (i = buffer_string_length(file); i > 0; i--) { - if (file->ptr[i] == '/') { - buffer_copy_string_len(dst, file->ptr, i); - return 0; - } - } - - return -1; -} - static handler_t stat_cache_fam_dir_check(server *srv, stat_cache_fam *scf, stat_cache_entry *sce, const buffer *name) { - if (0 != buffer_copy_dirname(scf->dir_name, name)) { + char *slash = !buffer_string_is_empty(name) + ? strrchr(name->ptr, '/') + : NULL; + if (NULL == slash) { log_error_write(srv, __FILE__, __LINE__, "sb", "no '/' found in filename:", name); return HANDLER_ERROR; } + scf->dirlen = (size_t)(slash - name->ptr); + if (0 == scf->dirlen) scf->dirlen = 1; /* root dir ("/") */ - scf->dir_ndx = hashme(CONST_BUF_LEN(scf->dir_name)); + scf->dir_ndx = hashme(name->ptr, scf->dirlen); scf->dirs = splaytree_splay(scf->dirs, scf->dir_ndx); @@ -286,7 +272,7 @@ static handler_t stat_cache_fam_dir_check(server *srv, stat_cache_fam *scf, stat scf->fam_dir = scf->dirs->data; /* check whether we got a collision */ - if (buffer_is_equal(scf->dir_name, scf->fam_dir->name)) { + if (buffer_is_equal_string(scf->fam_dir->name, name->ptr, scf->dirlen)) { /* test whether a found file cache entry is still ok */ if ((NULL != sce) && (scf->fam_dir->version == sce->dir_version)) { /* the stat()-cache entry is still ok */ @@ -309,15 +295,12 @@ static void stat_cache_fam_dir_monitor(server *srv, stat_cache_fam *scf, stat_ca if (NULL == fam_dir) { fam_dir = fam_dir_entry_init(); - buffer_copy_buffer(fam_dir->name, scf->dir_name); + buffer_copy_string_len(fam_dir->name, name->ptr, scf->dirlen); fam_dir->version = 1; - fam_dir->req = calloc(1, sizeof(FAMRequest)); - force_assert(NULL != fam_dir); - if (0 != FAMMonitorDirectory(&scf->fam, fam_dir->name->ptr, - fam_dir->req, fam_dir)) { + &fam_dir->req, fam_dir)) { log_error_write(srv, __FILE__, __LINE__, "sbsbs", "monitoring dir failed:", @@ -326,7 +309,7 @@ static void stat_cache_fam_dir_monitor(server *srv, stat_cache_fam *scf, stat_ca FamErrlist[FAMErrno]); fam_dir_entry_free(&scf->fam, fam_dir); - fam_dir = NULL; + return; } else { int osize = splaytree_size(scf->dirs); @@ -347,10 +330,7 @@ static void stat_cache_fam_dir_monitor(server *srv, stat_cache_fam *scf, stat_ca } /* bind the fam_fc to the stat() cache entry */ - - if (fam_dir) { - sce->dir_version = fam_dir->version; - } + sce->dir_version = fam_dir->version; } #endif