diff options
author | David Howells <dhowells@redhat.com> | 2006-10-11 04:22:19 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-11 14:14:25 -0400 |
commit | c636ebdb186bf37f98d3839f69293597723edb36 (patch) | |
tree | db1d54d355cd8030bf5d1645ce6bac8842f32690 /include | |
parent | 6ce315234aefcbc599dea390c15672156ebf9e7b (diff) |
[PATCH] VFS: Destroy the dentries contributed by a superblock on unmounting
The attached patch destroys all the dentries attached to a superblock in one go
by:
(1) Destroying the tree rooted at s_root.
(2) Destroying every entry in the anon list, one at a time.
(3) Each entry in the anon list has its subtree consumed from the leaves
inwards.
This reduces the amount of work generic_shutdown_super() does, and avoids
iterating through the dentry_unused list.
Note that locking is almost entirely absent in the shrink_dcache_for_umount*()
functions added by this patch. This is because:
(1) at the point the filesystem calls generic_shutdown_super(), it is not
permitted to further touch the superblock's set of dentries, and nor may
it remove aliases from inodes;
(2) the dcache memory shrinker now skips dentries that are being unmounted;
and
(3) the superblock no longer has any external references through which the VFS
can reach it.
Given these points, the only locking we need to do is when we remove dentries
from the unused list and the name hashes, which we do a directory's worth at a
time.
We also don't need to guard against reference counts going to zero unexpectedly
and removing bits of the tree we're working on as nothing else can call dput().
A cut down version of dentry_iput() has been folded into
shrink_dcache_for_umount_subtree() function. Apart from not needing to unlock
things, it also doesn't need to check for inotify watches.
In this version of the patch, the complaint about a dentry still being in use
has been expanded from a single BUG_ON() and now gives much more information.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: NeilBrown <neilb@suse.de>
Acked-by: Ian Kent <raven@themaw.net>
Cc: Trond Myklebust <trond.myklebust@fys.uio.no>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/dcache.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 44605be59409..63f64a9a5bf7 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -230,6 +230,7 @@ extern struct dentry * d_alloc_anon(struct inode *); | |||
230 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); | 230 | extern struct dentry * d_splice_alias(struct inode *, struct dentry *); |
231 | extern void shrink_dcache_sb(struct super_block *); | 231 | extern void shrink_dcache_sb(struct super_block *); |
232 | extern void shrink_dcache_parent(struct dentry *); | 232 | extern void shrink_dcache_parent(struct dentry *); |
233 | extern void shrink_dcache_for_umount(struct super_block *); | ||
233 | extern int d_invalidate(struct dentry *); | 234 | extern int d_invalidate(struct dentry *); |
234 | 235 | ||
235 | /* only used at mount-time */ | 236 | /* only used at mount-time */ |