forked from luck/tmp_suning_uos_patched
[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>
This commit is contained in:
parent
bcc5c7d2b6
commit
c35038beca
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 @@ static int select_submounts(struct vfsmount *parent, struct list_head *graveyard
|
|||
* 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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user