Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c35038be authored by Al Viro's avatar Al Viro
Browse files

[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: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent bcc5c7d2
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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
+0 −8
Original line number Diff line number Diff line
@@ -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);
}
+0 −1
Original line number Diff line number Diff line
@@ -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,
};
+0 −1
Original line number Diff line number Diff line
@@ -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);
}

/**
+10 −13
Original line number Diff line number Diff line
@@ -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.
Loading