X-Git-Url: https://git.tokkee.org/?p=fusedav.git;a=blobdiff_plain;f=src%2Fstatcache.c;h=28f3e275199d561d2274bcb5e79e0a6b6693f826;hp=3622a73a468f61c98abf5a0902c8c0636c13a0a2;hb=HEAD;hpb=868905c5d44902e293d9837bdcca3751e2b92dc8 diff --git a/src/statcache.c b/src/statcache.c index 3622a73..28f3e27 100644 --- a/src/statcache.c +++ b/src/statcache.c @@ -1,3 +1,31 @@ +/*** + Copyright (c) 2004-2006 Lennart Poettering + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include #include @@ -7,6 +35,7 @@ #include #include "statcache.h" +#include "filecache.h" #include "fusedav.h" #include @@ -16,7 +45,6 @@ struct dir_entry { struct dir_entry *next; - int is_dir; char filename[]; }; @@ -46,7 +74,7 @@ static uint32_t calc_hash(const char *s) { uint32_t h = 0; for (; *s; s++) { - h ^= * (uint8_t*) s; + h ^= * (const uint8_t*) s; h = (h << 8) | (h >> 24); } @@ -57,29 +85,36 @@ int stat_cache_get(const char *fn, struct stat *st) { uint32_t h; struct cache_entry *ce; int r = -1; + void *f; if (debug) fprintf(stderr, "CGET: %s\n", fn); - + assert(cache); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); pthread_mutex_lock(&stat_cache_mutex); - + if (ce->stat_info.valid && ce->stat_info.filename && ce->stat_info.hash == h && !strcmp(ce->stat_info.filename, fn) && time(NULL) <= ce->stat_info.dead) { - + *st = ce->stat_info.st; + + if ((f = file_cache_get(fn))) { + st->st_size = file_cache_get_size(f); + file_cache_unref(f); + } + r = 0; } pthread_mutex_unlock(&stat_cache_mutex); - + return r; } @@ -90,7 +125,7 @@ void stat_cache_set(const char *fn, const struct stat*st) { if (debug) fprintf(stderr, "CSET: %s\n", fn); assert(cache); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); @@ -101,7 +136,7 @@ void stat_cache_set(const char *fn, const struct stat*st) { ce->stat_info.filename = strdup(fn); ce->stat_info.hash = h; } - + ce->stat_info.st = *st; ce->stat_info.dead = time(NULL)+CACHE_TIMEOUT; ce->stat_info.valid = 1; @@ -114,7 +149,7 @@ void stat_cache_invalidate(const char*fn) { struct cache_entry *ce; assert(cache); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); @@ -123,7 +158,7 @@ void stat_cache_invalidate(const char*fn) { ce->stat_info.valid = 0; free(ce->stat_info.filename); ce->stat_info.filename = NULL; - + pthread_mutex_unlock(&stat_cache_mutex); } @@ -142,14 +177,14 @@ void dir_cache_begin(const char *fn) { struct cache_entry *ce; struct dir_entry *de = NULL, *de2 = NULL; assert(cache); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); - + pthread_mutex_lock(&dir_cache_mutex); if (!ce->dir_info.filling) { - + if (!ce->dir_info.filename || ce->dir_info.hash != h || strcmp(ce->dir_info.filename, fn)) { free(ce->dir_info.filename); ce->dir_info.filename = strdup(fn); @@ -165,7 +200,7 @@ void dir_cache_begin(const char *fn) { ce->dir_info.valid2 = 0; ce->dir_info.filling = 1; } - + pthread_mutex_unlock(&dir_cache_mutex); free_dir_entries(de); free_dir_entries(de2); @@ -176,12 +211,12 @@ void dir_cache_finish(const char *fn, int success) { struct cache_entry *ce; struct dir_entry *de = NULL; assert(cache); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); - + pthread_mutex_lock(&dir_cache_mutex); - + if (ce->dir_info.filling && ce->dir_info.filename && ce->dir_info.hash == h && @@ -190,11 +225,11 @@ void dir_cache_finish(const char *fn, int success) { assert(!ce->dir_info.valid2); if (success) { - + ce->dir_info.valid2 = 1; ce->dir_info.filling = 0; ce->dir_info.dead2 = time(NULL)+CACHE_TIMEOUT; - + if (!ce->dir_info.in_use) { de = ce->dir_info.entries; ce->dir_info.entries = ce->dir_info.entries2; @@ -203,7 +238,7 @@ void dir_cache_finish(const char *fn, int success) { ce->dir_info.valid2 = 0; ce->dir_info.valid = 1; } - + } else { ce->dir_info.filling = 0; de = ce->dir_info.entries2; @@ -215,16 +250,16 @@ void dir_cache_finish(const char *fn, int success) { free_dir_entries(de); } -void dir_cache_add(const char *fn, const char *subdir, int is_dir) { +void dir_cache_add(const char *fn, const char *subdir) { uint32_t h; struct cache_entry *ce; assert(cache); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); - + pthread_mutex_lock(&dir_cache_mutex); - + if (ce->dir_info.filling && ce->dir_info.filename && ce->dir_info.hash == h && @@ -238,8 +273,7 @@ void dir_cache_add(const char *fn, const char *subdir, int is_dir) { assert(n); strcpy(n->filename, subdir); - n->is_dir = is_dir; - + n->next = ce->dir_info.entries2; ce->dir_info.entries2 = n; } @@ -247,18 +281,19 @@ void dir_cache_add(const char *fn, const char *subdir, int is_dir) { pthread_mutex_unlock(&dir_cache_mutex); } -int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *subdir, int is_dir, void *user), void *user) { +int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *subdir, void *user), void *user) { uint32_t h; struct cache_entry *ce; struct dir_entry *de = NULL; - assert(cache && f); int r = -1; - + + assert(cache && f); + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); - + pthread_mutex_lock(&dir_cache_mutex); - + if (ce->dir_info.valid && ce->dir_info.filename && ce->dir_info.hash == h && @@ -269,7 +304,7 @@ int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *su pthread_mutex_unlock(&dir_cache_mutex); for (de = ce->dir_info.entries; de; de = de->next) - f(fn, de->filename, de->is_dir, user); + f(fn, de->filename, user); pthread_mutex_lock(&dir_cache_mutex); ce->dir_info.in_use = 0; @@ -285,23 +320,23 @@ int dir_cache_enumerate(const char *fn, void (*f) (const char*fn, const char *su r = 0; } - + pthread_mutex_unlock(&dir_cache_mutex); free_dir_entries(de); return r; -} +} void dir_cache_invalidate(const char*fn) { uint32_t h; struct cache_entry *ce; struct dir_entry *de = NULL; assert(cache && fn); - + h = calc_hash(fn); ce = cache + (h % CACHE_SIZE); pthread_mutex_lock(&dir_cache_mutex); - + if (ce->dir_info.valid && ce->dir_info.filename && ce->dir_info.hash == h && @@ -311,7 +346,7 @@ void dir_cache_invalidate(const char*fn) { de = ce->dir_info.entries; ce->dir_info.entries = NULL; } - + pthread_mutex_unlock(&dir_cache_mutex); free_dir_entries(de); } @@ -326,7 +361,7 @@ void dir_cache_invalidate_parent(const char *fn) { if (p[l-1] == '/') p[l-1] = 0; } - + dir_cache_invalidate(p); free(p); } else @@ -351,11 +386,11 @@ void cache_free(void) { } void cache_alloc(void) { - + if (cache) return; cache = malloc(sizeof(struct cache_entry)*CACHE_SIZE); + assert(cache); memset(cache, 0, sizeof(struct cache_entry)*CACHE_SIZE); } -