diff options
| -rw-r--r-- | fs/afs/internal.h | 1 | ||||
| -rw-r--r-- | fs/afs/mntpt.c | 8 | ||||
| -rw-r--r-- | fs/afs/super.c | 1 | ||||
| -rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 1 | ||||
| -rw-r--r-- | fs/namespace.c | 23 | ||||
| -rw-r--r-- | fs/nfs/super.c | 2 | ||||
| -rw-r--r-- | include/linux/mount.h | 1 |
7 files changed, 10 insertions, 27 deletions
diff --git a/fs/afs/internal.h b/fs/afs/internal.h index 5ca3625cd39e..9ba16edc0af2 100644 --- a/fs/afs/internal.h +++ b/fs/afs/internal.h | |||
| @@ -573,7 +573,6 @@ extern const struct file_operations afs_mntpt_file_operations; | |||
| 573 | 573 | ||
| 574 | extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); | 574 | extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *); |
| 575 | extern void afs_mntpt_kill_timer(void); | 575 | extern void afs_mntpt_kill_timer(void); |
| 576 | extern void afs_umount_begin(struct vfsmount *, int); | ||
| 577 | 576 | ||
| 578 | /* | 577 | /* |
| 579 | * proc.c | 578 | * proc.c |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index a3510b8ba3e7..2f5503902c37 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
| @@ -283,11 +283,3 @@ void afs_mntpt_kill_timer(void) | |||
| 283 | cancel_delayed_work(&afs_mntpt_expiry_timer); | 283 | cancel_delayed_work(&afs_mntpt_expiry_timer); |
| 284 | flush_scheduled_work(); | 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 | } | ||
diff --git a/fs/afs/super.c b/fs/afs/super.c index 36bbce45f44b..4b572b801d8d 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
| @@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = { | |||
| 50 | .write_inode = afs_write_inode, | 50 | .write_inode = afs_write_inode, |
| 51 | .destroy_inode = afs_destroy_inode, | 51 | .destroy_inode = afs_destroy_inode, |
| 52 | .clear_inode = afs_clear_inode, | 52 | .clear_inode = afs_clear_inode, |
| 53 | .umount_begin = afs_umount_begin, | ||
| 54 | .put_super = afs_put_super, | 53 | .put_super = afs_put_super, |
| 55 | .show_options = generic_show_options, | 54 | .show_options = generic_show_options, |
| 56 | }; | 55 | }; |
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index a1a95b027136..56c924033b78 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c | |||
| @@ -33,7 +33,6 @@ void dfs_shrink_umount_helper(struct vfsmount *vfsmnt) | |||
| 33 | { | 33 | { |
| 34 | mark_mounts_for_expiry(&cifs_dfs_automount_list); | 34 | mark_mounts_for_expiry(&cifs_dfs_automount_list); |
| 35 | mark_mounts_for_expiry(&cifs_dfs_automount_list); | 35 | mark_mounts_for_expiry(&cifs_dfs_automount_list); |
| 36 | shrink_submounts(vfsmnt, &cifs_dfs_automount_list); | ||
| 37 | } | 36 | } |
| 38 | 37 | ||
| 39 | /** | 38 | /** |
diff --git a/fs/namespace.c b/fs/namespace.c index 1c78917ec930..7bd74b25930c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -581,6 +581,8 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) | |||
| 581 | } | 581 | } |
| 582 | } | 582 | } |
| 583 | 583 | ||
| 584 | static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts); | ||
| 585 | |||
| 584 | static int do_umount(struct vfsmount *mnt, int flags) | 586 | static int do_umount(struct vfsmount *mnt, int flags) |
| 585 | { | 587 | { |
| 586 | struct super_block *sb = mnt->mnt_sb; | 588 | struct super_block *sb = mnt->mnt_sb; |
| @@ -653,6 +655,9 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
| 653 | spin_lock(&vfsmount_lock); | 655 | spin_lock(&vfsmount_lock); |
| 654 | event++; | 656 | event++; |
| 655 | 657 | ||
| 658 | if (!(flags & MNT_DETACH)) | ||
| 659 | shrink_submounts(mnt, &umount_list); | ||
| 660 | |||
| 656 | retval = -EBUSY; | 661 | retval = -EBUSY; |
| 657 | if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { | 662 | if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { |
| 658 | if (!list_empty(&mnt->mnt_list)) | 663 | if (!list_empty(&mnt->mnt_list)) |
| @@ -1302,30 +1307,22 @@ resume: | |||
| 1302 | * process a list of expirable mountpoints with the intent of discarding any | 1307 | * process a list of expirable mountpoints with the intent of discarding any |
| 1303 | * submounts of a specific parent mountpoint | 1308 | * submounts of a specific parent mountpoint |
| 1304 | */ | 1309 | */ |
| 1305 | void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts) | 1310 | static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts) |
| 1306 | { | 1311 | { |
| 1307 | LIST_HEAD(graveyard); | 1312 | LIST_HEAD(graveyard); |
| 1308 | LIST_HEAD(umounts); | 1313 | struct vfsmount *m; |
| 1309 | struct vfsmount *mnt; | ||
| 1310 | 1314 | ||
| 1311 | down_write(&namespace_sem); | ||
| 1312 | spin_lock(&vfsmount_lock); | ||
| 1313 | /* extract submounts of 'mountpoint' from the expiration list */ | 1315 | /* extract submounts of 'mountpoint' from the expiration list */ |
| 1314 | while (select_submounts(mountpoint, &graveyard)) { | 1316 | while (select_submounts(mnt, &graveyard)) { |
| 1315 | while (!list_empty(&graveyard)) { | 1317 | while (!list_empty(&graveyard)) { |
| 1316 | mnt = list_first_entry(&graveyard, struct vfsmount, | 1318 | m = list_first_entry(&graveyard, struct vfsmount, |
| 1317 | mnt_expire); | 1319 | mnt_expire); |
| 1318 | touch_mnt_namespace(mnt->mnt_ns); | 1320 | touch_mnt_namespace(mnt->mnt_ns); |
| 1319 | umount_tree(mnt, 1, &umounts); | 1321 | umount_tree(mnt, 1, umounts); |
| 1320 | } | 1322 | } |
| 1321 | } | 1323 | } |
| 1322 | spin_unlock(&vfsmount_lock); | ||
| 1323 | up_write(&namespace_sem); | ||
| 1324 | release_mounts(&umounts); | ||
| 1325 | } | 1324 | } |
| 1326 | 1325 | ||
| 1327 | EXPORT_SYMBOL_GPL(shrink_submounts); | ||
| 1328 | |||
| 1329 | /* | 1326 | /* |
| 1330 | * Some copy_from_user() implementations do not return the exact number of | 1327 | * Some copy_from_user() implementations do not return the exact number of |
| 1331 | * bytes remaining to copy on a fault. But copy_mount_options() requires that. | 1328 | * bytes remaining to copy on a fault. But copy_mount_options() requires that. |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index dd4dfcd632ec..f9219024f31a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -589,8 +589,6 @@ static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) | |||
| 589 | struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb); | 589 | struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb); |
| 590 | struct rpc_clnt *rpc; | 590 | struct rpc_clnt *rpc; |
| 591 | 591 | ||
| 592 | shrink_submounts(vfsmnt, &nfs_automount_list); | ||
| 593 | |||
| 594 | if (!(flags & MNT_FORCE)) | 592 | if (!(flags & MNT_FORCE)) |
| 595 | return; | 593 | return; |
| 596 | /* -EIO all pending I/O */ | 594 | /* -EIO all pending I/O */ |
diff --git a/include/linux/mount.h b/include/linux/mount.h index dac5e67ff3ee..5ee2df217cdf 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h | |||
| @@ -99,7 +99,6 @@ extern int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd, | |||
| 99 | int mnt_flags, struct list_head *fslist); | 99 | int mnt_flags, struct list_head *fslist); |
| 100 | 100 | ||
| 101 | extern void mark_mounts_for_expiry(struct list_head *mounts); | 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 | extern spinlock_t vfsmount_lock; | 103 | extern spinlock_t vfsmount_lock; |
| 105 | extern dev_t name_to_dev_t(char *name); | 104 | extern dev_t name_to_dev_t(char *name); |
