[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>

Al Viro c35038be bcc5c7d2

+10 -27
-1
fs/afs/internal.h
··· 573 573 574 574 extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); 575 575 extern void afs_mntpt_kill_timer(void); 576 - extern void afs_umount_begin(struct vfsmount *, int); 577 576 578 577 /* 579 578 * proc.c
-8
fs/afs/mntpt.c
··· 283 283 cancel_delayed_work(&afs_mntpt_expiry_timer); 284 284 flush_scheduled_work(); 285 285 } 286 - 287 - /* 288 - * begin unmount by attempting to remove all automounted mountpoints we added 289 - */ 290 - void afs_umount_begin(struct vfsmount *vfsmnt, int flags) 291 - { 292 - shrink_submounts(vfsmnt, &afs_vfsmounts); 293 - }
-1
fs/afs/super.c
··· 50 50 .write_inode = afs_write_inode, 51 51 .destroy_inode = afs_destroy_inode, 52 52 .clear_inode = afs_clear_inode, 53 - .umount_begin = afs_umount_begin, 54 53 .put_super = afs_put_super, 55 54 .show_options = generic_show_options, 56 55 };
-1
fs/cifs/cifs_dfs_ref.c
··· 33 33 { 34 34 mark_mounts_for_expiry(&cifs_dfs_automount_list); 35 35 mark_mounts_for_expiry(&cifs_dfs_automount_list); 36 - shrink_submounts(vfsmnt, &cifs_dfs_automount_list); 37 36 } 38 37 39 38 /**
+10 -13
fs/namespace.c
··· 581 581 } 582 582 } 583 583 584 + static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts); 585 + 584 586 static int do_umount(struct vfsmount *mnt, int flags) 585 587 { 586 588 struct super_block *sb = mnt->mnt_sb; ··· 654 652 down_write(&namespace_sem); 655 653 spin_lock(&vfsmount_lock); 656 654 event++; 655 + 656 + if (!(flags & MNT_DETACH)) 657 + shrink_submounts(mnt, &umount_list); 657 658 658 659 retval = -EBUSY; 659 660 if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { ··· 1307 1302 * process a list of expirable mountpoints with the intent of discarding any 1308 1303 * submounts of a specific parent mountpoint 1309 1304 */ 1310 - void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts) 1305 + static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts) 1311 1306 { 1312 1307 LIST_HEAD(graveyard); 1313 - LIST_HEAD(umounts); 1314 - struct vfsmount *mnt; 1308 + struct vfsmount *m; 1315 1309 1316 - down_write(&namespace_sem); 1317 - spin_lock(&vfsmount_lock); 1318 1310 /* extract submounts of 'mountpoint' from the expiration list */ 1319 - while (select_submounts(mountpoint, &graveyard)) { 1311 + while (select_submounts(mnt, &graveyard)) { 1320 1312 while (!list_empty(&graveyard)) { 1321 - mnt = list_first_entry(&graveyard, struct vfsmount, 1313 + m = list_first_entry(&graveyard, struct vfsmount, 1322 1314 mnt_expire); 1323 1315 touch_mnt_namespace(mnt->mnt_ns); 1324 - umount_tree(mnt, 1, &umounts); 1316 + umount_tree(mnt, 1, umounts); 1325 1317 } 1326 1318 } 1327 - spin_unlock(&vfsmount_lock); 1328 - up_write(&namespace_sem); 1329 - release_mounts(&umounts); 1330 1319 } 1331 - 1332 - EXPORT_SYMBOL_GPL(shrink_submounts); 1333 1320 1334 1321 /* 1335 1322 * Some copy_from_user() implementations do not return the exact number of
-2
fs/nfs/super.c
··· 589 589 struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb); 590 590 struct rpc_clnt *rpc; 591 591 592 - shrink_submounts(vfsmnt, &nfs_automount_list); 593 - 594 592 if (!(flags & MNT_FORCE)) 595 593 return; 596 594 /* -EIO all pending I/O */
-1
include/linux/mount.h
··· 99 99 int mnt_flags, struct list_head *fslist); 100 100 101 101 extern void mark_mounts_for_expiry(struct list_head *mounts); 102 - extern void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts); 103 102 104 103 extern spinlock_t vfsmount_lock; 105 104 extern dev_t name_to_dev_t(char *name);