Skip to content

Commit 2763d11

Browse files
author
Al Viro
committed
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 <[email protected]>
1 parent 4edbe13 commit 2763d11

File tree

1 file changed

+28
-34
lines changed

1 file changed

+28
-34
lines changed

fs/namespace.c

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -820,16 +820,6 @@ static struct mountpoint *unhash_mnt(struct mount *mnt)
820820
return mp;
821821
}
822822

823-
/*
824-
* vfsmount lock must be held for write
825-
*/
826-
static void detach_mnt(struct mount *mnt, struct path *old_path)
827-
{
828-
old_path->dentry = dget(mnt->mnt_mountpoint);
829-
old_path->mnt = &mnt->mnt_parent->mnt;
830-
put_mountpoint(unhash_mnt(mnt));
831-
}
832-
833823
/*
834824
* vfsmount lock must be held for write
835825
*/
@@ -2045,7 +2035,7 @@ int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
20452035
static int attach_recursive_mnt(struct mount *source_mnt,
20462036
struct mount *dest_mnt,
20472037
struct mountpoint *dest_mp,
2048-
struct path *parent_path)
2038+
bool moving)
20492039
{
20502040
struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
20512041
HLIST_HEAD(tree_list);
@@ -2063,7 +2053,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
20632053
return PTR_ERR(smp);
20642054

20652055
/* Is there space to add these mounts to the mount namespace? */
2066-
if (!parent_path) {
2056+
if (!moving) {
20672057
err = count_mounts(ns, source_mnt);
20682058
if (err)
20692059
goto out;
@@ -2082,8 +2072,8 @@ static int attach_recursive_mnt(struct mount *source_mnt,
20822072
} else {
20832073
lock_mount_hash();
20842074
}
2085-
if (parent_path) {
2086-
detach_mnt(source_mnt, parent_path);
2075+
if (moving) {
2076+
unhash_mnt(source_mnt);
20872077
attach_mnt(source_mnt, dest_mnt, dest_mp);
20882078
touch_mnt_namespace(source_mnt->mnt_ns);
20892079
} else {
@@ -2181,7 +2171,7 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
21812171
d_is_dir(mnt->mnt.mnt_root))
21822172
return -ENOTDIR;
21832173

2184-
return attach_recursive_mnt(mnt, p, mp, NULL);
2174+
return attach_recursive_mnt(mnt, p, mp, false);
21852175
}
21862176

21872177
/*
@@ -2574,11 +2564,11 @@ static bool check_for_nsfs_mounts(struct mount *subtree)
25742564

25752565
static int do_move_mount(struct path *old_path, struct path *new_path)
25762566
{
2577-
struct path parent_path = {.mnt = NULL, .dentry = NULL};
25782567
struct mnt_namespace *ns;
25792568
struct mount *p;
25802569
struct mount *old;
2581-
struct mountpoint *mp;
2570+
struct mount *parent;
2571+
struct mountpoint *mp, *old_mp;
25822572
int err;
25832573
bool attached;
25842574

@@ -2588,7 +2578,9 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
25882578

25892579
old = real_mount(old_path->mnt);
25902580
p = real_mount(new_path->mnt);
2581+
parent = old->mnt_parent;
25912582
attached = mnt_has_parent(old);
2583+
old_mp = old->mnt_mp;
25922584
ns = old->mnt_ns;
25932585

25942586
err = -EINVAL;
@@ -2616,7 +2608,7 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
26162608
/*
26172609
* Don't move a mount residing in a shared parent.
26182610
*/
2619-
if (attached && IS_MNT_SHARED(old->mnt_parent))
2611+
if (attached && IS_MNT_SHARED(parent))
26202612
goto out;
26212613
/*
26222614
* 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)
26322624
goto out;
26332625

26342626
err = attach_recursive_mnt(old, real_mount(new_path->mnt), mp,
2635-
attached ? &parent_path : NULL);
2627+
attached);
26362628
if (err)
26372629
goto out;
26382630

26392631
/* if the mount is moved, it should no longer be expire
26402632
* automatically */
26412633
list_del_init(&old->mnt_expire);
2634+
if (attached)
2635+
put_mountpoint(old_mp);
26422636
out:
26432637
unlock_mount(mp);
26442638
if (!err) {
2645-
path_put(&parent_path);
2646-
if (!attached)
2639+
if (attached)
2640+
mntput_no_expire(parent);
2641+
else
26472642
free_mnt_ns(ns);
26482643
}
26492644
return err;
@@ -3586,8 +3581,8 @@ EXPORT_SYMBOL(path_is_under);
35863581
SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
35873582
const char __user *, put_old)
35883583
{
3589-
struct path new, old, parent_path, root_parent, root;
3590-
struct mount *new_mnt, *root_mnt, *old_mnt;
3584+
struct path new, old, root;
3585+
struct mount *new_mnt, *root_mnt, *old_mnt, *root_parent, *ex_parent;
35913586
struct mountpoint *old_mp, *root_mp;
35923587
int error;
35933588

@@ -3616,9 +3611,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
36163611
new_mnt = real_mount(new.mnt);
36173612
root_mnt = real_mount(root.mnt);
36183613
old_mnt = real_mount(old.mnt);
3614+
ex_parent = new_mnt->mnt_parent;
3615+
root_parent = root_mnt->mnt_parent;
36193616
if (IS_MNT_SHARED(old_mnt) ||
3620-
IS_MNT_SHARED(new_mnt->mnt_parent) ||
3621-
IS_MNT_SHARED(root_mnt->mnt_parent))
3617+
IS_MNT_SHARED(ex_parent) ||
3618+
IS_MNT_SHARED(root_parent))
36223619
goto out4;
36233620
if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
36243621
goto out4;
@@ -3635,7 +3632,6 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
36353632
goto out4; /* not a mountpoint */
36363633
if (!mnt_has_parent(root_mnt))
36373634
goto out4; /* not attached */
3638-
root_mp = root_mnt->mnt_mp;
36393635
if (new.mnt->mnt_root != new.dentry)
36403636
goto out4; /* not a mountpoint */
36413637
if (!mnt_has_parent(new_mnt))
@@ -3646,18 +3642,18 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
36463642
/* make certain new is below the root */
36473643
if (!is_path_reachable(new_mnt, new.dentry, &root))
36483644
goto out4;
3649-
root_mp->m_count++; /* pin it so it won't go away */
36503645
lock_mount_hash();
3651-
detach_mnt(new_mnt, &parent_path);
3652-
detach_mnt(root_mnt, &root_parent);
3646+
umount_mnt(new_mnt);
3647+
root_mp = unhash_mnt(root_mnt); /* we'll need its mountpoint */
36533648
if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
36543649
new_mnt->mnt.mnt_flags |= MNT_LOCKED;
36553650
root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
36563651
}
36573652
/* mount old root on put_old */
36583653
attach_mnt(root_mnt, old_mnt, old_mp);
36593654
/* mount new_root on / */
3660-
attach_mnt(new_mnt, real_mount(root_parent.mnt), root_mp);
3655+
attach_mnt(new_mnt, root_parent, root_mp);
3656+
mnt_add_count(root_parent, -1);
36613657
touch_mnt_namespace(current->nsproxy->mnt_ns);
36623658
/* A moved mount should not expire automatically */
36633659
list_del_init(&new_mnt->mnt_expire);
@@ -3667,10 +3663,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
36673663
error = 0;
36683664
out4:
36693665
unlock_mount(old_mp);
3670-
if (!error) {
3671-
path_put(&root_parent);
3672-
path_put(&parent_path);
3673-
}
3666+
if (!error)
3667+
mntput_no_expire(ex_parent);
36743668
out3:
36753669
path_put(&root);
36763670
out2:

0 commit comments

Comments
 (0)