aboutsummaryrefslogtreecommitdiffstats
path: root/lib/fuse.c
diff options
context:
space:
mode:
authorMiklos Szeredi <mszeredi@suse.cz>2012-08-14 11:18:07 +0200
committerMiklos Szeredi <mszeredi@suse.cz>2012-08-14 11:18:07 +0200
commit1061a0a2d90148bd2e7f32e1e694399db2dbe087 (patch)
tree7e720dfbe3e7a42dd35d8aa2734395c206ce4b12 /lib/fuse.c
parentefeac22bfa65c845c04adb5e70e6de33b0104fa3 (diff)
downloadandroid_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
Diffstat (limited to 'lib/fuse.c')
-rw-r--r--lib/fuse.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/lib/fuse.c b/lib/fuse.c
index 3c7f642..f801f84 100644
--- a/lib/fuse.c
+++ b/lib/fuse.c
@@ -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;