diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2012-08-14 14:03:10 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2012-08-14 14:03:10 +0200 |
commit | 07b4946b5bee7f60d533b8b21c1eea16dbb86917 (patch) | |
tree | 8964f5acb853ac60f276841a5a8a65c43c0f8145 | |
parent | 5957ea2fd952cc7158f5632655d706abfa789e95 (diff) | |
parent | fdff523325bf49dc1cb9b62787dcf4ae22898d0f (diff) | |
download | fuse-07b4946b5bee7f60d533b8b21c1eea16dbb86917.tar.gz |
Merge branch 'fuse_2_9_bugfix'
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | lib/fuse.c | 28 |
2 files changed, 23 insertions, 13 deletions
@@ -1,3 +1,11 @@ +2012-08-14 Miklos Szeredi <miklos@szeredi.hu> + + * Not unhashing the name in forget (commit on 2011-12-09) broke + the forget logic in a subtle way, resulting in "fuse internal + error: node NNN not found" and causing the filesystem daemon to + abort. Fix by incrementing the node refcount if nlookup goes from + zero to one. Reported by Kyle Lippincott + 2012-08-13 Miklos Szeredi <miklos@szeredi.hu> * Fix linking against GNU libiconv. Patch by Natanael Copa @@ -321,12 +321,12 @@ static void list_add(struct list_head *new, struct list_head *prev, prev->next = new; } -static void list_add_head(struct list_head *new, struct list_head *head) +static inline void list_add_head(struct list_head *new, struct list_head *head) { list_add(new, head, head->next); } -static void list_add_tail(struct list_head *new, struct list_head *head) +static inline void list_add_tail(struct list_head *new, struct list_head *head) { list_add(new, head->prev, head); } @@ -419,6 +419,7 @@ static struct node *alloc_node(struct fuse *f) list_del(&slab->list); list_add_tail(&slab->list, &f->full_slabs); } + memset(node, 0, sizeof(struct node)); return (struct node *) node; } @@ -812,6 +813,13 @@ static struct node *lookup_node(struct fuse *f, fuse_ino_t parent, return NULL; } +static void inc_nlookup(struct node *node) +{ + if (!node->nlookup) + node->refctr++; + node->nlookup++; +} + static struct node *find_node(struct fuse *f, fuse_ino_t parent, const char *name) { @@ -827,15 +835,11 @@ static struct node *find_node(struct fuse *f, fuse_ino_t parent, if (node == NULL) goto out_err; - if (f->conf.remember) - node->nlookup = 1; - node->refctr = 1; node->nodeid = next_id(f); node->generation = f->generation; - node->open_count = 0; - node->is_hidden = 0; - node->treelock = 0; - node->ticket = 0; + if (f->conf.remember) + inc_nlookup(node); + if (hash_name(f, node, parent, name) == -1) { free_node(f, node); node = NULL; @@ -849,7 +853,7 @@ static struct node *find_node(struct fuse *f, fuse_ino_t parent, } else if (lru_enabled(f) && node->nlookup == 1) { remove_node_lru(node); } - node->nlookup ++; + inc_nlookup(node); out_err: pthread_mutex_unlock(&f->lock); return node; @@ -4494,9 +4498,7 @@ struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args, root->parent = NULL; root->nodeid = FUSE_ROOT_ID; - root->generation = 0; - root->refctr = 1; - root->nlookup = 1; + inc_nlookup(root); hash_id(f, root); return f; |