mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-15 16:53:54 +08:00
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
|
* 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 = real_mount(path->mnt);
|
||||||
struct mount *parent;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
mnt_flags &= ~MNT_INTERNAL_FLAGS;
|
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))) {
|
if (unlikely(!check_mnt(parent))) {
|
||||||
/* that's acceptable only for automounts done in private ns */
|
/* that's acceptable only for automounts done in private ns */
|
||||||
if (!(mnt_flags & MNT_SHRINKABLE))
|
if (!(mnt_flags & MNT_SHRINKABLE))
|
||||||
goto unlock;
|
return -EINVAL;
|
||||||
/* ... and for those we'd better have mountpoint still alive */
|
/* ... and for those we'd better have mountpoint still alive */
|
||||||
if (!parent->mnt_ns)
|
if (!parent->mnt_ns)
|
||||||
goto unlock;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Refuse the same filesystem on the same mount point */
|
/* Refuse the same filesystem on the same mount point */
|
||||||
err = -EBUSY;
|
|
||||||
if (path->mnt->mnt_sb == newmnt->mnt.mnt_sb &&
|
if (path->mnt->mnt_sb == newmnt->mnt.mnt_sb &&
|
||||||
path->mnt->mnt_root == path->dentry)
|
path->mnt->mnt_root == path->dentry)
|
||||||
goto unlock;
|
return -EBUSY;
|
||||||
|
|
||||||
err = -EINVAL;
|
|
||||||
if (d_is_symlink(newmnt->mnt.mnt_root))
|
if (d_is_symlink(newmnt->mnt.mnt_root))
|
||||||
goto unlock;
|
return -EINVAL;
|
||||||
|
|
||||||
newmnt->mnt.mnt_flags = mnt_flags;
|
newmnt->mnt.mnt_flags = mnt_flags;
|
||||||
err = graft_tree(newmnt, parent, mp);
|
return graft_tree(newmnt, parent, mp);
|
||||||
|
|
||||||
unlock:
|
|
||||||
unlock_mount(mp);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags);
|
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)
|
unsigned int mnt_flags)
|
||||||
{
|
{
|
||||||
struct vfsmount *mnt;
|
struct vfsmount *mnt;
|
||||||
|
struct mountpoint *mp;
|
||||||
struct super_block *sb = fc->root->d_sb;
|
struct super_block *sb = fc->root->d_sb;
|
||||||
int error;
|
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);
|
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)
|
if (error < 0)
|
||||||
mntput(mnt);
|
mntput(mnt);
|
||||||
return error;
|
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)
|
int finish_automount(struct vfsmount *m, struct path *path)
|
||||||
{
|
{
|
||||||
struct mount *mnt = real_mount(m);
|
struct mount *mnt = real_mount(m);
|
||||||
|
struct mountpoint *mp;
|
||||||
int err;
|
int err;
|
||||||
/* The new mount record should have at least 2 refs to prevent it being
|
/* The new mount record should have at least 2 refs to prevent it being
|
||||||
* expired before we get a chance to add it
|
* expired before we get a chance to add it
|
||||||
@ -2842,7 +2837,13 @@ int finish_automount(struct vfsmount *m, struct path *path)
|
|||||||
goto fail;
|
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)
|
if (!err)
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
|
Loading…
Reference in New Issue
Block a user