[PATCH] do shrink_submounts() for all fs types
Al Viro [Sat, 22 Mar 2008 04:46:23 +0000 (00:46 -0400)]
... and take it out of ->umount_begin() instances.  Call with all locks
already taken (by do_umount()) and leave calling release_mounts() to
caller (it will do release_mounts() anyway, so we can just put into
the same list).

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

fs/afs/internal.h
fs/afs/mntpt.c
fs/afs/super.c
fs/cifs/cifs_dfs_ref.c
fs/namespace.c
fs/nfs/super.c
include/linux/mount.h

index 5ca3625..9ba16ed 100644 (file)
@@ -573,7 +573,6 @@ extern const struct file_operations afs_mntpt_file_operations;
 
 extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *);
 extern void afs_mntpt_kill_timer(void);
-extern void afs_umount_begin(struct vfsmount *, int);
 
 /*
  * proc.c
index a3510b8..2f55039 100644 (file)
@@ -283,11 +283,3 @@ void afs_mntpt_kill_timer(void)
        cancel_delayed_work(&afs_mntpt_expiry_timer);
        flush_scheduled_work();
 }
-
-/*
- * begin unmount by attempting to remove all automounted mountpoints we added
- */
-void afs_umount_begin(struct vfsmount *vfsmnt, int flags)
-{
-       shrink_submounts(vfsmnt, &afs_vfsmounts);
-}
index 36bbce4..4b572b8 100644 (file)
@@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = {
        .write_inode    = afs_write_inode,
        .destroy_inode  = afs_destroy_inode,
        .clear_inode    = afs_clear_inode,
-       .umount_begin   = afs_umount_begin,
        .put_super      = afs_put_super,
        .show_options   = generic_show_options,
 };
index a1a95b0..56c9240 100644 (file)
@@ -33,7 +33,6 @@ void dfs_shrink_umount_helper(struct vfsmount *vfsmnt)
 {
        mark_mounts_for_expiry(&cifs_dfs_automount_list);
        mark_mounts_for_expiry(&cifs_dfs_automount_list);
-       shrink_submounts(vfsmnt, &cifs_dfs_automount_list);
 }
 
 /**
index 1c78917..7bd74b2 100644 (file)
@@ -581,6 +581,8 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
        }
 }
 
+static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts);
+
 static int do_umount(struct vfsmount *mnt, int flags)
 {
        struct super_block *sb = mnt->mnt_sb;
@@ -653,6 +655,9 @@ static int do_umount(struct vfsmount *mnt, int flags)
        spin_lock(&vfsmount_lock);
        event++;
 
+       if (!(flags & MNT_DETACH))
+               shrink_submounts(mnt, &umount_list);
+
        retval = -EBUSY;
        if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
                if (!list_empty(&mnt->mnt_list))
@@ -1302,30 +1307,22 @@ resume:
  * process a list of expirable mountpoints with the intent of discarding any
  * submounts of a specific parent mountpoint
  */
-void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts)
+static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts)
 {
        LIST_HEAD(graveyard);
-       LIST_HEAD(umounts);
-       struct vfsmount *mnt;
+       struct vfsmount *m;
 
-       down_write(&namespace_sem);
-       spin_lock(&vfsmount_lock);
        /* extract submounts of 'mountpoint' from the expiration list */
-       while (select_submounts(mountpoint, &graveyard)) {
+       while (select_submounts(mnt, &graveyard)) {
                while (!list_empty(&graveyard)) {
-                       mnt = list_first_entry(&graveyard, struct vfsmount,
+                       m = list_first_entry(&graveyard, struct vfsmount,
                                                mnt_expire);
                        touch_mnt_namespace(mnt->mnt_ns);
-                       umount_tree(mnt, 1, &umounts);
+                       umount_tree(mnt, 1, umounts);
                }
        }
-       spin_unlock(&vfsmount_lock);
-       up_write(&namespace_sem);
-       release_mounts(&umounts);
 }
 
-EXPORT_SYMBOL_GPL(shrink_submounts);
-
 /*
  * Some copy_from_user() implementations do not return the exact number of
  * bytes remaining to copy on a fault.  But copy_mount_options() requires that.
index dd4dfcd..f921902 100644 (file)
@@ -589,8 +589,6 @@ static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
        struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
        struct rpc_clnt *rpc;
 
-       shrink_submounts(vfsmnt, &nfs_automount_list);
-
        if (!(flags & MNT_FORCE))
                return;
        /* -EIO all pending I/O */
index dac5e67..5ee2df2 100644 (file)
@@ -99,7 +99,6 @@ extern int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
                        int mnt_flags, struct list_head *fslist);
 
 extern void mark_mounts_for_expiry(struct list_head *mounts);
-extern void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts);
 
 extern spinlock_t vfsmount_lock;
 extern dev_t name_to_dev_t(char *name);