diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-03-22 00:46:23 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-03-27 20:47:58 -0400 |
commit | c35038becad0adb0e25261fff66d85b1a6ddd0c2 (patch) | |
tree | 1d375d74ef5b4c3641768697b2ff8f4992916dc5 | |
parent | bcc5c7d2b692e5319db00b0dd020ce98723103b1 (diff) |
[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>
-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); |