diff options
author | Miklos Szeredi <mszeredi@suse.cz> | 2012-08-14 11:18:07 +0200 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2012-08-14 11:18:07 +0200 |
commit | 1061a0a2d90148bd2e7f32e1e694399db2dbe087 (patch) | |
tree | 7e720dfbe3e7a42dd35d8aa2734395c206ce4b12 | |
parent | efeac22bfa65c845c04adb5e70e6de33b0104fa3 (diff) | |
download | android_external_fuse-1061a0a2d90148bd2e7f32e1e694399db2dbe087.tar.gz android_external_fuse-1061a0a2d90148bd2e7f32e1e694399db2dbe087.tar.bz2 android_external_fuse-1061a0a2d90148bd2e7f32e1e694399db2dbe087.zip |
Fix "fuse internal error: node NNN not found"
Commit 4dc7e675bb (Don't unhash name in FORGET) 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
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | lib/fuse.c | 16 |
2 files changed, 20 insertions, 4 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 @@ -816,6 +816,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) { @@ -831,15 +838,16 @@ 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->refctr = 0; 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; @@ -853,7 +861,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; |