From mboxrd@z Thu Jan 1 00:00:00 1970 From: Valerie Aurora Subject: [PATCH 31/74] union-mount: Free union stack on removal of topmost dentry from dcache Date: Tue, 22 Mar 2011 18:59:07 -0700 Message-ID: <1300845590-14184-32-git-send-email-valerie.aurora@gmail.com> References: <1300845590-14184-1-git-send-email-valerie.aurora@gmail.com> Cc: viro@zeniv.linux.org.uk, Jan Blunck , Valerie Aurora To: linux-fsdevel@vger.kernel.org, linux@vger.kernel.org Return-path: Received: from mail-iw0-f174.google.com ([209.85.214.174]:47988 "EHLO mail-iw0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756657Ab1CWCBn (ORCPT ); Tue, 22 Mar 2011 22:01:43 -0400 In-Reply-To: <1300845590-14184-1-git-send-email-valerie.aurora@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org List-ID: From: Jan Blunck If a dentry is removed from dentry cache because its usage count drops to zero, its union stack is freed too. Signed-off-by: Valerie Aurora --- fs/dcache.c | 11 +++++++++++ fs/namespace.c | 2 ++ 2 files changed, 13 insertions(+), 0 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 566acf7..6b11519 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -34,6 +34,7 @@ #include #include #include "internal.h" +#include "union.h" int sysctl_vfs_cache_pressure __read_mostly = 100; EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); @@ -175,6 +176,7 @@ static struct dentry *d_kill(struct dentry *dentry) dentry_stat.nr_dentry--; /* For d_free, below */ /*drops the locks, at that point nobody can reach this dentry */ dentry_iput(dentry); + d_free_unions(dentry); if (IS_ROOT(dentry)) parent = NULL; else @@ -697,6 +699,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) iput(inode); } + d_free_unions(dentry); d_free(dentry); /* finished when we fall off the top of the tree, @@ -1547,6 +1550,7 @@ void d_delete(struct dentry * dentry) if (atomic_read(&dentry->d_count) == 1) { dentry->d_flags &= ~DCACHE_CANT_MOUNT; dentry_iput(dentry); + d_free_unions(dentry); fsnotify_nameremove(dentry, isdir); return; } @@ -1557,6 +1561,13 @@ void d_delete(struct dentry * dentry) spin_unlock(&dentry->d_lock); spin_unlock(&dcache_lock); + /* + * Remove any associated unions. While someone still has this + * directory open (ref count > 0), we could not have deleted + * it unless it was empty, and therefore has no references to + * directories below it. So we don't need the unions. + */ + d_free_unions(dentry); fsnotify_nameremove(dentry, isdir); } EXPORT_SYMBOL(d_delete); diff --git a/fs/namespace.c b/fs/namespace.c index 054eb7d..5de05e4 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -36,6 +36,7 @@ #include #include "pnode.h" #include "internal.h" +#include "union.h" #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head)) #define HASH_SIZE (1UL << HASH_SHIFT) @@ -1108,6 +1109,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) propagate_umount(kill); list_for_each_entry(p, kill, mnt_hash) { + d_free_unions(p->mnt_root); list_del_init(&p->mnt_expire); list_del_init(&p->mnt_list); __touch_mnt_namespace(p->mnt_ns); -- 1.7.0.4