do_add_mount(): lift lock_mount/unlock_mount into callers
preparation to finish_automount() fix (next commit) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
bb6d3fb354
commit
8f11538ebe
|
@ -2697,45 +2697,32 @@ static int do_move_mount_old(struct path *path, const char *old_name)
|
|||
/*
|
||||
* add a mount into a namespace's mount tree
|
||||
*/
|
||||
static int do_add_mount(struct mount *newmnt, struct path *path, int mnt_flags)
|
||||
static int do_add_mount(struct mount *newmnt, struct mountpoint *mp,
|
||||
struct path *path, int mnt_flags)
|
||||
{
|
||||
struct mountpoint *mp;
|
||||
struct mount *parent;
|
||||
int err;
|
||||
struct mount *parent = real_mount(path->mnt);
|
||||
|
||||
mnt_flags &= ~MNT_INTERNAL_FLAGS;
|
||||
|
||||
mp = lock_mount(path);
|
||||
if (IS_ERR(mp))
|
||||
return PTR_ERR(mp);
|
||||
|
||||
parent = real_mount(path->mnt);
|
||||
err = -EINVAL;
|
||||
if (unlikely(!check_mnt(parent))) {
|
||||
/* that's acceptable only for automounts done in private ns */
|
||||
if (!(mnt_flags & MNT_SHRINKABLE))
|
||||
goto unlock;
|
||||
return -EINVAL;
|
||||
/* ... and for those we'd better have mountpoint still alive */
|
||||
if (!parent->mnt_ns)
|
||||
goto unlock;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Refuse the same filesystem on the same mount point */
|
||||
err = -EBUSY;
|
||||
if (path->mnt->mnt_sb == newmnt->mnt.mnt_sb &&
|
||||
path->mnt->mnt_root == path->dentry)
|
||||
goto unlock;
|
||||
return -EBUSY;
|
||||
|
||||
err = -EINVAL;
|
||||
if (d_is_symlink(newmnt->mnt.mnt_root))
|
||||
goto unlock;
|
||||
return -EINVAL;
|
||||
|
||||
newmnt->mnt.mnt_flags = mnt_flags;
|
||||
err = graft_tree(newmnt, parent, mp);
|
||||
|
||||
unlock:
|
||||
unlock_mount(mp);
|
||||
return err;
|
||||
return graft_tree(newmnt, parent, mp);
|
||||
}
|
||||
|
||||
static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags);
|
||||
|
@ -2748,6 +2735,7 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
|
|||
unsigned int mnt_flags)
|
||||
{
|
||||
struct vfsmount *mnt;
|
||||
struct mountpoint *mp;
|
||||
struct super_block *sb = fc->root->d_sb;
|
||||
int error;
|
||||
|
||||
|
@ -2768,7 +2756,13 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
|
|||
|
||||
mnt_warn_timestamp_expiry(mountpoint, mnt);
|
||||
|
||||
error = do_add_mount(real_mount(mnt), mountpoint, mnt_flags);
|
||||
mp = lock_mount(mountpoint);
|
||||
if (IS_ERR(mp)) {
|
||||
mntput(mnt);
|
||||
return PTR_ERR(mp);
|
||||
}
|
||||
error = do_add_mount(real_mount(mnt), mp, mountpoint, mnt_flags);
|
||||
unlock_mount(mp);
|
||||
if (error < 0)
|
||||
mntput(mnt);
|
||||
return error;
|
||||
|
@ -2830,6 +2824,7 @@ static int do_new_mount(struct path *path, const char *fstype, int sb_flags,
|
|||
int finish_automount(struct vfsmount *m, struct path *path)
|
||||
{
|
||||
struct mount *mnt = real_mount(m);
|
||||
struct mountpoint *mp;
|
||||
int err;
|
||||
/* The new mount record should have at least 2 refs to prevent it being
|
||||
* expired before we get a chance to add it
|
||||
|
@ -2842,7 +2837,13 @@ int finish_automount(struct vfsmount *m, struct path *path)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
err = do_add_mount(mnt, path, path->mnt->mnt_flags | MNT_SHRINKABLE);
|
||||
mp = lock_mount(path);
|
||||
if (IS_ERR(mp)) {
|
||||
err = PTR_ERR(mp);
|
||||
goto fail;
|
||||
}
|
||||
err = do_add_mount(mnt, mp, path, path->mnt->mnt_flags | MNT_SHRINKABLE);
|
||||
unlock_mount(mp);
|
||||
if (!err)
|
||||
return 0;
|
||||
fail:
|
||||
|
|
Loading…
Reference in New Issue