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>
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
{
struct dentry *parent;
static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
{
struct dentry *parent;
BUG_ON(!IS_ROOT(dentry));
BUG_ON(!IS_ROOT(dentry));
atomic_dec(&parent->d_count);
list_del(&dentry->d_u.d_child);
atomic_dec(&parent->d_count);
list_del(&dentry->d_u.d_child);
- dentry_stat.nr_dentry--; /* For d_free, below */
inode = dentry->d_inode;
if (inode) {
inode = dentry->d_inode;
if (inode) {
* otherwise we ascend to the parent and move to the
* next sibling if there is one */
if (!parent)
* otherwise we ascend to the parent and move to the
* next sibling if there is one */
if (!parent)
dentry = list_entry(dentry->d_subdirs.next,
struct dentry, d_u.d_child);
}
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);