diff --git a/src/statcache.c b/src/statcache.c
index 3622a73a468f61c98abf5a0902c8c0636c13a0a2..28f3e275199d561d2274bcb5e79e0a6b6693f826 100644 (file)
--- a/src/statcache.c
+++ b/src/statcache.c
+/***
+ 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 <config.h>
+#endif
+
#include <stdio.h>
#include <inttypes.h>
#include <time.h>
#include <assert.h>
#include "statcache.h"
+#include "filecache.h"
#include "fusedav.h"
#include <ne_uri.h>
struct dir_entry {
struct dir_entry *next;
- int is_dir;
char filename[];
};
uint32_t h = 0;
for (; *s; s++) {
- h ^= * (uint8_t*) s;
+ h ^= * (const uint8_t*) s;
h = (h << 8) | (h >> 24);
}
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;
}
if (debug)
fprintf(stderr, "CSET: %s\n", fn);
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
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;
struct cache_entry *ce;
assert(cache);
-
+
h = calc_hash(fn);
ce = cache + (h % CACHE_SIZE);
ce->stat_info.valid = 0;
free(ce->stat_info.filename);
ce->stat_info.filename = NULL;
-
+
pthread_mutex_unlock(&stat_cache_mutex);
}
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);
ce->dir_info.valid2 = 0;
ce->dir_info.filling = 1;
}
-
+
pthread_mutex_unlock(&dir_cache_mutex);
free_dir_entries(de);
free_dir_entries(de2);
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 &&
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;
ce->dir_info.valid2 = 0;
ce->dir_info.valid = 1;
}
-
+
} else {
ce->dir_info.filling = 0;
de = ce->dir_info.entries2;
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 &&
assert(n);
strcpy(n->filename, subdir);
- n->is_dir = is_dir;
-
+
n->next = ce->dir_info.entries2;
ce->dir_info.entries2 = n;
}
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 &&
de = ce->dir_info.entries;
ce->dir_info.entries = NULL;
}
-
+
pthread_mutex_unlock(&dir_cache_mutex);
free_dir_entries(de);
}
if (p[l-1] == '/')
p[l-1] = 0;
}
-
+
dir_cache_invalidate(p);
free(p);
} else
}
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);
}
-