aboutsummaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-10-11 04:22:19 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-11 14:14:25 -0400
commitc636ebdb186bf37f98d3839f69293597723edb36 (patch)
treedb1d54d355cd8030bf5d1645ce6bac8842f32690 /fs/super.c
parent6ce315234aefcbc599dea390c15672156ebf9e7b (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 'fs/super.c')
-rw-r--r--fs/super.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/super.c b/fs/super.c
index aec99ddbe53f..47e554c12e76 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -260,17 +260,17 @@ int fsync_super(struct super_block *sb)
260 * that need destruction out of superblock, call generic_shutdown_super() 260 * that need destruction out of superblock, call generic_shutdown_super()
261 * and release aforementioned objects. Note: dentries and inodes _are_ 261 * and release aforementioned objects. Note: dentries and inodes _are_
262 * taken care of and do not need specific handling. 262 * taken care of and do not need specific handling.
263 *
264 * Upon calling this function, the filesystem may no longer alter or
265 * rearrange the set of dentries belonging to this super_block, nor may it
266 * change the attachments of dentries to inodes.
263 */ 267 */
264void generic_shutdown_super(struct super_block *sb) 268void generic_shutdown_super(struct super_block *sb)
265{ 269{
266 struct dentry *root = sb->s_root;
267 struct super_operations *sop = sb->s_op; 270 struct super_operations *sop = sb->s_op;
268 271
269 if (root) { 272 if (sb->s_root) {
270 sb->s_root = NULL; 273 shrink_dcache_for_umount(sb);
271 shrink_dcache_parent(root);
272 shrink_dcache_sb(sb);
273 dput(root);
274 fsync_super(sb); 274 fsync_super(sb);
275 lock_super(sb); 275 lock_super(sb);
276 sb->s_flags &= ~MS_ACTIVE; 276 sb->s_flags &= ~MS_ACTIVE;