mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 04:20:53 +07:00
get rid of detach_mnt()
Lift getting the original mount (dentry is actually not needed at all) of the mountpoint into the callers - to do_move_mount() and pivot_root() level. That simplifies the cleanup in those and allows to get saner arguments for attach_mnt_recursive(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
4edbe133f8
commit
2763d11912
@ -820,16 +820,6 @@ static struct mountpoint *unhash_mnt(struct mount *mnt)
|
|||||||
return mp;
|
return mp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* vfsmount lock must be held for write
|
|
||||||
*/
|
|
||||||
static void detach_mnt(struct mount *mnt, struct path *old_path)
|
|
||||||
{
|
|
||||||
old_path->dentry = dget(mnt->mnt_mountpoint);
|
|
||||||
old_path->mnt = &mnt->mnt_parent->mnt;
|
|
||||||
put_mountpoint(unhash_mnt(mnt));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* vfsmount lock must be held for write
|
* vfsmount lock must be held for write
|
||||||
*/
|
*/
|
||||||
@ -2045,7 +2035,7 @@ int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
|
|||||||
static int attach_recursive_mnt(struct mount *source_mnt,
|
static int attach_recursive_mnt(struct mount *source_mnt,
|
||||||
struct mount *dest_mnt,
|
struct mount *dest_mnt,
|
||||||
struct mountpoint *dest_mp,
|
struct mountpoint *dest_mp,
|
||||||
struct path *parent_path)
|
bool moving)
|
||||||
{
|
{
|
||||||
struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
|
struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
|
||||||
HLIST_HEAD(tree_list);
|
HLIST_HEAD(tree_list);
|
||||||
@ -2063,7 +2053,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
|||||||
return PTR_ERR(smp);
|
return PTR_ERR(smp);
|
||||||
|
|
||||||
/* Is there space to add these mounts to the mount namespace? */
|
/* Is there space to add these mounts to the mount namespace? */
|
||||||
if (!parent_path) {
|
if (!moving) {
|
||||||
err = count_mounts(ns, source_mnt);
|
err = count_mounts(ns, source_mnt);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
@ -2082,8 +2072,8 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
|||||||
} else {
|
} else {
|
||||||
lock_mount_hash();
|
lock_mount_hash();
|
||||||
}
|
}
|
||||||
if (parent_path) {
|
if (moving) {
|
||||||
detach_mnt(source_mnt, parent_path);
|
unhash_mnt(source_mnt);
|
||||||
attach_mnt(source_mnt, dest_mnt, dest_mp);
|
attach_mnt(source_mnt, dest_mnt, dest_mp);
|
||||||
touch_mnt_namespace(source_mnt->mnt_ns);
|
touch_mnt_namespace(source_mnt->mnt_ns);
|
||||||
} else {
|
} else {
|
||||||
@ -2181,7 +2171,7 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
|
|||||||
d_is_dir(mnt->mnt.mnt_root))
|
d_is_dir(mnt->mnt.mnt_root))
|
||||||
return -ENOTDIR;
|
return -ENOTDIR;
|
||||||
|
|
||||||
return attach_recursive_mnt(mnt, p, mp, NULL);
|
return attach_recursive_mnt(mnt, p, mp, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2574,11 +2564,11 @@ static bool check_for_nsfs_mounts(struct mount *subtree)
|
|||||||
|
|
||||||
static int do_move_mount(struct path *old_path, struct path *new_path)
|
static int do_move_mount(struct path *old_path, struct path *new_path)
|
||||||
{
|
{
|
||||||
struct path parent_path = {.mnt = NULL, .dentry = NULL};
|
|
||||||
struct mnt_namespace *ns;
|
struct mnt_namespace *ns;
|
||||||
struct mount *p;
|
struct mount *p;
|
||||||
struct mount *old;
|
struct mount *old;
|
||||||
struct mountpoint *mp;
|
struct mount *parent;
|
||||||
|
struct mountpoint *mp, *old_mp;
|
||||||
int err;
|
int err;
|
||||||
bool attached;
|
bool attached;
|
||||||
|
|
||||||
@ -2588,7 +2578,9 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
|
|||||||
|
|
||||||
old = real_mount(old_path->mnt);
|
old = real_mount(old_path->mnt);
|
||||||
p = real_mount(new_path->mnt);
|
p = real_mount(new_path->mnt);
|
||||||
|
parent = old->mnt_parent;
|
||||||
attached = mnt_has_parent(old);
|
attached = mnt_has_parent(old);
|
||||||
|
old_mp = old->mnt_mp;
|
||||||
ns = old->mnt_ns;
|
ns = old->mnt_ns;
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
@ -2616,7 +2608,7 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
|
|||||||
/*
|
/*
|
||||||
* Don't move a mount residing in a shared parent.
|
* Don't move a mount residing in a shared parent.
|
||||||
*/
|
*/
|
||||||
if (attached && IS_MNT_SHARED(old->mnt_parent))
|
if (attached && IS_MNT_SHARED(parent))
|
||||||
goto out;
|
goto out;
|
||||||
/*
|
/*
|
||||||
* Don't move a mount tree containing unbindable mounts to a destination
|
* Don't move a mount tree containing unbindable mounts to a destination
|
||||||
@ -2632,18 +2624,21 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
|
|||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = attach_recursive_mnt(old, real_mount(new_path->mnt), mp,
|
err = attach_recursive_mnt(old, real_mount(new_path->mnt), mp,
|
||||||
attached ? &parent_path : NULL);
|
attached);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* if the mount is moved, it should no longer be expire
|
/* if the mount is moved, it should no longer be expire
|
||||||
* automatically */
|
* automatically */
|
||||||
list_del_init(&old->mnt_expire);
|
list_del_init(&old->mnt_expire);
|
||||||
|
if (attached)
|
||||||
|
put_mountpoint(old_mp);
|
||||||
out:
|
out:
|
||||||
unlock_mount(mp);
|
unlock_mount(mp);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
path_put(&parent_path);
|
if (attached)
|
||||||
if (!attached)
|
mntput_no_expire(parent);
|
||||||
|
else
|
||||||
free_mnt_ns(ns);
|
free_mnt_ns(ns);
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
@ -3586,8 +3581,8 @@ EXPORT_SYMBOL(path_is_under);
|
|||||||
SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||||
const char __user *, put_old)
|
const char __user *, put_old)
|
||||||
{
|
{
|
||||||
struct path new, old, parent_path, root_parent, root;
|
struct path new, old, root;
|
||||||
struct mount *new_mnt, *root_mnt, *old_mnt;
|
struct mount *new_mnt, *root_mnt, *old_mnt, *root_parent, *ex_parent;
|
||||||
struct mountpoint *old_mp, *root_mp;
|
struct mountpoint *old_mp, *root_mp;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
@ -3616,9 +3611,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
|||||||
new_mnt = real_mount(new.mnt);
|
new_mnt = real_mount(new.mnt);
|
||||||
root_mnt = real_mount(root.mnt);
|
root_mnt = real_mount(root.mnt);
|
||||||
old_mnt = real_mount(old.mnt);
|
old_mnt = real_mount(old.mnt);
|
||||||
|
ex_parent = new_mnt->mnt_parent;
|
||||||
|
root_parent = root_mnt->mnt_parent;
|
||||||
if (IS_MNT_SHARED(old_mnt) ||
|
if (IS_MNT_SHARED(old_mnt) ||
|
||||||
IS_MNT_SHARED(new_mnt->mnt_parent) ||
|
IS_MNT_SHARED(ex_parent) ||
|
||||||
IS_MNT_SHARED(root_mnt->mnt_parent))
|
IS_MNT_SHARED(root_parent))
|
||||||
goto out4;
|
goto out4;
|
||||||
if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
|
if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
|
||||||
goto out4;
|
goto out4;
|
||||||
@ -3635,7 +3632,6 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
|||||||
goto out4; /* not a mountpoint */
|
goto out4; /* not a mountpoint */
|
||||||
if (!mnt_has_parent(root_mnt))
|
if (!mnt_has_parent(root_mnt))
|
||||||
goto out4; /* not attached */
|
goto out4; /* not attached */
|
||||||
root_mp = root_mnt->mnt_mp;
|
|
||||||
if (new.mnt->mnt_root != new.dentry)
|
if (new.mnt->mnt_root != new.dentry)
|
||||||
goto out4; /* not a mountpoint */
|
goto out4; /* not a mountpoint */
|
||||||
if (!mnt_has_parent(new_mnt))
|
if (!mnt_has_parent(new_mnt))
|
||||||
@ -3646,10 +3642,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
|||||||
/* make certain new is below the root */
|
/* make certain new is below the root */
|
||||||
if (!is_path_reachable(new_mnt, new.dentry, &root))
|
if (!is_path_reachable(new_mnt, new.dentry, &root))
|
||||||
goto out4;
|
goto out4;
|
||||||
root_mp->m_count++; /* pin it so it won't go away */
|
|
||||||
lock_mount_hash();
|
lock_mount_hash();
|
||||||
detach_mnt(new_mnt, &parent_path);
|
umount_mnt(new_mnt);
|
||||||
detach_mnt(root_mnt, &root_parent);
|
root_mp = unhash_mnt(root_mnt); /* we'll need its mountpoint */
|
||||||
if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
|
if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
|
||||||
new_mnt->mnt.mnt_flags |= MNT_LOCKED;
|
new_mnt->mnt.mnt_flags |= MNT_LOCKED;
|
||||||
root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
|
root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
|
||||||
@ -3657,7 +3652,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
|||||||
/* mount old root on put_old */
|
/* mount old root on put_old */
|
||||||
attach_mnt(root_mnt, old_mnt, old_mp);
|
attach_mnt(root_mnt, old_mnt, old_mp);
|
||||||
/* mount new_root on / */
|
/* mount new_root on / */
|
||||||
attach_mnt(new_mnt, real_mount(root_parent.mnt), root_mp);
|
attach_mnt(new_mnt, root_parent, root_mp);
|
||||||
|
mnt_add_count(root_parent, -1);
|
||||||
touch_mnt_namespace(current->nsproxy->mnt_ns);
|
touch_mnt_namespace(current->nsproxy->mnt_ns);
|
||||||
/* A moved mount should not expire automatically */
|
/* A moved mount should not expire automatically */
|
||||||
list_del_init(&new_mnt->mnt_expire);
|
list_del_init(&new_mnt->mnt_expire);
|
||||||
@ -3667,10 +3663,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
|||||||
error = 0;
|
error = 0;
|
||||||
out4:
|
out4:
|
||||||
unlock_mount(old_mp);
|
unlock_mount(old_mp);
|
||||||
if (!error) {
|
if (!error)
|
||||||
path_put(&root_parent);
|
mntput_no_expire(ex_parent);
|
||||||
path_put(&parent_path);
|
|
||||||
}
|
|
||||||
out3:
|
out3:
|
||||||
path_put(&root);
|
path_put(&root);
|
||||||
out2:
|
out2:
|
||||||
|
Loading…
Reference in New Issue
Block a user