[PATCH] do shrink_submounts() for all fs types

... 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>
diff --git a/fs/namespace.c b/fs/namespace.c
index 1c78917..7bd74b2 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -581,6 +581,8 @@
 	}
 }
 
+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 @@
 	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 @@
  * 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.