aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-10-28 13:38:46 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-28 14:30:53 -0400
commitf87135762de4328c6f17897e803e6909bc056feb (patch)
treebf182df7b7ca8326c7ed3590693ac1e276b24a14 /fs/dcache.c
parent6eac3f93f5e6b7256fb20b7608d62ec192da12be (diff)
[PATCH] VFS: Fix an error in unused dentry counting
With Vasily Averin <vvs@sw.ru> Fix an error in unused dentry counting in shrink_dcache_for_umount_subtree() in which the count is modified without the dcache_lock held. Signed-off-by: David Howells <dhowells@redhat.com> Cc: Vasily Averin <vvs@sw.ru> Cc: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index a5b76b647c6d..fd4a428998ef 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -557,6 +557,7 @@ repeat:
557static void shrink_dcache_for_umount_subtree(struct dentry *dentry) 557static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
558{ 558{
559 struct dentry *parent; 559 struct dentry *parent;
560 unsigned detached = 0;
560 561
561 BUG_ON(!IS_ROOT(dentry)); 562 BUG_ON(!IS_ROOT(dentry));
562 563
@@ -621,7 +622,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
621 atomic_dec(&parent->d_count); 622 atomic_dec(&parent->d_count);
622 623
623 list_del(&dentry->d_u.d_child); 624 list_del(&dentry->d_u.d_child);
624 dentry_stat.nr_dentry--; /* For d_free, below */ 625 detached++;
625 626
626 inode = dentry->d_inode; 627 inode = dentry->d_inode;
627 if (inode) { 628 if (inode) {
@@ -639,7 +640,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
639 * otherwise we ascend to the parent and move to the 640 * otherwise we ascend to the parent and move to the
640 * next sibling if there is one */ 641 * next sibling if there is one */
641 if (!parent) 642 if (!parent)
642 return; 643 goto out;
643 644
644 dentry = parent; 645 dentry = parent;
645 646
@@ -648,6 +649,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
648 dentry = list_entry(dentry->d_subdirs.next, 649 dentry = list_entry(dentry->d_subdirs.next,
649 struct dentry, d_u.d_child); 650 struct dentry, d_u.d_child);
650 } 651 }
652out:
653 /* several dentries were freed, need to correct nr_dentry */
654 spin_lock(&dcache_lock);
655 dentry_stat.nr_dentry -= detached;
656 spin_unlock(&dcache_lock);
651} 657}
652 658
653/* 659/*