aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@ZenIV.linux.org.uk>2010-04-29 03:10:43 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2010-05-26 14:27:07 -0700
commit5ea176dcda8200cce3ca9e208fba5ab49ebb786d (patch)
treed50c5d714d12b9c9d262210bbe47e7ab3847c5e2
parentd130b918879aa06a82cfac3bec5ec88e79a05f30 (diff)
nfs d_revalidate() is too trigger-happy with d_drop()
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>
-rw-r--r--fs/nfs/dir.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index e195f67e4018..ee7ed217b2ce 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -826,6 +826,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);