summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9>2006-09-21 14:53:14 +0000
committerjan <jan@152afb58-edef-0310-8abb-c4023f1b3aa9>2006-09-21 14:53:14 +0000
commit3aa4a0b591d7475ccb41d727c3675b4ada8667e9 (patch)
treebb85ff0ec42d79ca52d43da00972bd836e0493bf
parentfbe923a02631046a127401c487f815f480272710 (diff)
downloadlighttpd-3aa4a0b591d7475ccb41d727c3675b4ada8667e9.tar.gz
handle follow-symlink in the stat-cache
- added the follow-symlink into the hash-key - delete all versions if a file/dir is moved or deleted git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.11-ssl-fixes@1332 152afb58-edef-0310-8abb-c4023f1b3aa9
-rw-r--r--src/base.h1
-rw-r--r--src/stat_cache.c52
2 files changed, 31 insertions, 22 deletions
diff --git a/src/base.h b/src/base.h
index 35af7c86..15caee00 100644
--- a/src/base.h
+++ b/src/base.h
@@ -229,6 +229,7 @@ typedef struct {
FAMConnection *fam;
int fam_fcce_ndx;
#endif
+ buffer *hash_key; /* temp-store for the hash-key */
} stat_cache;
typedef struct {
diff --git a/src/stat_cache.c b/src/stat_cache.c
index bda9514d..a4f31a4e 100644
--- a/src/stat_cache.c
+++ b/src/stat_cache.c
@@ -109,6 +109,7 @@ stat_cache *stat_cache_init(void) {
fc = calloc(1, sizeof(*fc));
fc->dir_name = buffer_init();
+ fc->hash_key = buffer_init();
#ifdef HAVE_FAM_H
fc->fam = calloc(1, sizeof(*fc->fam));
#endif
@@ -182,6 +183,7 @@ void stat_cache_free(stat_cache *sc) {
}
buffer_free(sc->dir_name);
+ buffer_free(sc->hash_key);
#ifdef HAVE_FAM_H
while (sc->dirs) {
@@ -256,7 +258,7 @@ handler_t stat_cache_handle_fdevent(void *_srv, void *_fce, int revent) {
FAMEvent fe;
fam_dir_entry *fam_dir;
splay_tree *node;
- int ndx;
+ int ndx, j;
FAMNextEvent(sc->fam, &fe);
@@ -274,20 +276,25 @@ handler_t stat_cache_handle_fdevent(void *_srv, void *_fce, int revent) {
/* file/dir is still here */
if (fe.code == FAMChanged) break;
- buffer_copy_string(sc->dir_name, fe.filename);
+ /* we have 2 versions, follow and no-follow-symlink */
- ndx = hashme(sc->dir_name);
+ for (j = 0; j < 2; j++) {
+ buffer_copy_string(sc->hash_key, fe.filename);
+ buffer_append_long(sc->hash_key, j);
- sc->dirs = splaytree_splay(sc->dirs, ndx);
- node = sc->dirs;
-
- if (node && (node->key == ndx)) {
- int osize = splaytree_size(sc->dirs);
-
- fam_dir_entry_free(node->data);
- sc->dirs = splaytree_delete(sc->dirs, ndx);
+ ndx = hashme(sc->hash_key);
- assert(osize - 1 == splaytree_size(sc->dirs));
+ sc->dirs = splaytree_splay(sc->dirs, ndx);
+ node = sc->dirs;
+
+ if (node && (node->key == ndx)) {
+ int osize = splaytree_size(sc->dirs);
+
+ fam_dir_entry_free(node->data);
+ sc->dirs = splaytree_delete(sc->dirs, ndx);
+
+ assert(osize - 1 == splaytree_size(sc->dirs));
+ }
}
break;
default:
@@ -378,7 +385,10 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
sc = srv->stat_cache;
- file_ndx = hashme(name);
+ buffer_copy_string_buffer(sc->hash_key, name);
+ buffer_append_long(sc->hash_key, con->conf.follow_symlink);
+
+ file_ndx = hashme(sc->hash_key);
sc->files = splaytree_splay(sc->files, file_ndx);
#ifdef DEBUG_STAT_CACHE
@@ -437,8 +447,11 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
if (0 != buffer_copy_dirname(sc->dir_name, name)) {
SEGFAULT();
}
+
+ buffer_copy_string_buffer(sc->hash_key, sc->dir_name);
+ buffer_append_long(sc->hash_key, con->conf.follow_symlink);
- dir_ndx = hashme(sc->dir_name);
+ dir_ndx = hashme(sc->hash_key);
sc->dirs = splaytree_splay(sc->dirs, dir_ndx);
@@ -527,15 +540,10 @@ handler_t stat_cache_get_entry(server *srv, connection *con, buffer *name, stat_
* */
#ifdef HAVE_LSTAT
sce->is_symlink = 0;
- /*
- * normally we want to only check for symlinks if we should block
- * symlinks. for some weird reason it doesnt check for symlinks at all
- * in some cases. so we disable it for now.
- * this can have a little performance slow down.
- *
- * if (!con->conf.follow_symlink) {
+
+ /* we want to only check for symlinks if we should block symlinks.
*/
- if (1) {
+ if (!con->conf.follow_symlink) {
if (stat_cache_lstat(srv, name, &lst) == 0) {
#ifdef DEBUG_STAT_CACHE
log_error_write(srv, __FILE__, __LINE__, "sb",