Don't unhash name in FORGET
authorMiklos Szeredi <mszeredi@suse.cz>
Fri, 9 Dec 2011 15:07:55 +0000 (16:07 +0100)
committerMiklos Szeredi <mszeredi@suse.cz>
Fri, 9 Dec 2011 15:07:55 +0000 (16:07 +0100)
This resulted in ENOENT being returned for unlinked but still open files if the
kernel sent a FORGET request for the parent directory.

Discovered with fs_racer in LTP.

ChangeLog
lib/fuse.c

index ba1f5e27d70076d62c40284b27b7aa72e3ea68b2..3f9ba399522674c2725dc3947ffdc7722e722148 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,10 @@
 
        * Fix hang in wait_on_path().  Reported by Ville Silventoinen
 
+       * Don't unhash name in FORGET.  This resulted in ENOENT being
+       returned for unlinked but still open files if the kernel sent a
+       FORGET request for the parent directory.
+
 2011-12-08  Miklos Szeredi <miklos@szeredi.hu>
 
        * Fix build if FUSE_NODE_SLAB is not defined.  Patch by Emmanuel
index 9073daf6b60522472303231d85bcf55d1171fe6a..e01f4504c5ad7b0acc87dbb22c30b6f0856695de 100644 (file)
@@ -775,7 +775,7 @@ static void delete_node(struct fuse *f, struct node *node)
                        (unsigned long long) node->nodeid);
 
        assert(node->treelock == 0);
-       assert(!node->name);
+       unhash_name(f, node);
        if (lru_enabled(f))
                remove_node_lru(node);
        unhash_id(f, node);
@@ -1258,7 +1258,6 @@ static void forget_node(struct fuse *f, fuse_ino_t nodeid, uint64_t nlookup)
        assert(node->nlookup >= nlookup);
        node->nlookup -= nlookup;
        if (!node->nlookup) {
-               unhash_name(f, node);
                unref_node(f, node);
        } else if (lru_enabled(f) && node->nlookup == 1) {
                set_forget_time(f, node);