]> git.hungrycats.org Git - linux/commitdiff
nfs d_revalidate() is too trigger-happy with d_drop()
authorAl Viro <viro@ZenIV.linux.org.uk>
Thu, 29 Apr 2010 02:10:43 +0000 (03:10 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 12 May 2010 22:02:40 +0000 (15:02 -0700)
commit d9e80b7de91db05c1c4d2e5ebbfd70b3b3ba0e0f upstream.

If dentry found stale happens to be a root of disconnected tree, we
can't d_drop() it; its d_hash is actually part of s_anon and d_drop()
would simply hide it from shrink_dcache_for_umount(), leading to
all sorts of fun, including busy inodes on umount and oopsen after
that.

Bug had been there since at least 2006 (commit c636eb already has it),
so it's definitely -stable fodder.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/nfs/dir.c

index af6948d6faf2ff4aa7fc5ca37cab2e0d67a300e1..b5d55d39fb791c6be8ace806c3ee6b08d904485a 100644 (file)
@@ -837,6 +837,8 @@ out_zap_parent:
                /* If we have submounts, don't unhash ! */
                if (have_submounts(dentry))
                        goto out_valid;
+               if (dentry->d_flags & DCACHE_DISCONNECTED)
+                       goto out_valid;
                shrink_dcache_parent(dentry);
        }
        d_drop(dentry);