mirror of https://gitee.com/openkylin/linux.git
[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>
This commit is contained in:
parent
6eac3f93f5
commit
f87135762d
10
fs/dcache.c
10
fs/dcache.c
|
@ -557,6 +557,7 @@ void shrink_dcache_sb(struct super_block * sb)
|
|||
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
|
||||
{
|
||||
struct dentry *parent;
|
||||
unsigned detached = 0;
|
||||
|
||||
BUG_ON(!IS_ROOT(dentry));
|
||||
|
||||
|
@ -621,7 +622,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
|
|||
atomic_dec(&parent->d_count);
|
||||
|
||||
list_del(&dentry->d_u.d_child);
|
||||
dentry_stat.nr_dentry--; /* For d_free, below */
|
||||
detached++;
|
||||
|
||||
inode = dentry->d_inode;
|
||||
if (inode) {
|
||||
|
@ -639,7 +640,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
|
|||
* otherwise we ascend to the parent and move to the
|
||||
* next sibling if there is one */
|
||||
if (!parent)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
dentry = parent;
|
||||
|
||||
|
@ -648,6 +649,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
|
|||
dentry = list_entry(dentry->d_subdirs.next,
|
||||
struct dentry, d_u.d_child);
|
||||
}
|
||||
out:
|
||||
/* several dentries were freed, need to correct nr_dentry */
|
||||
spin_lock(&dcache_lock);
|
||||
dentry_stat.nr_dentry -= detached;
|
||||
spin_unlock(&dcache_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue