aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2019-06-30 19:18:53 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2019-07-16 22:50:11 -0400
commit2763d11912317a12318135ca03e592bb6df65624 (patch)
tree1a6c87b01ca0debc003a888b2e4ded3c9c11daeb
parent4edbe133f851c9e3a2f2a1db367e826b01e72594 (diff)
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>
-rw-r--r--fs/namespace.c62
1 files changed, 28 insertions, 34 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index e0902fda6f07..46316ba15615 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -823,16 +823,6 @@ static struct mountpoint *unhash_mnt(struct mount *mnt)
823/* 823/*
824 * vfsmount lock must be held for write 824 * vfsmount lock must be held for write
825 */ 825 */
826static 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
833/*
834 * vfsmount lock must be held for write
835 */
836static void umount_mnt(struct mount *mnt) 826static void umount_mnt(struct mount *mnt)
837{ 827{
838 put_mountpoint(unhash_mnt(mnt)); 828 put_mountpoint(unhash_mnt(mnt));
@@ -2045,7 +2035,7 @@ int count_mounts(struct mnt_namespace *ns, struct mount *mnt)
2045static int attach_recursive_mnt(struct mount *source_mnt, 2035static int attach_recursive_mnt(struct mount *source_mnt,
2046 struct mount *dest_mnt, 2036 struct mount *dest_mnt,
2047 struct mountpoint *dest_mp, 2037 struct mountpoint *dest_mp,
2048 struct path *parent_path) 2038 bool moving)
2049{ 2039{
2050 struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; 2040 struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;
2051 HLIST_HEAD(tree_list); 2041 HLIST_HEAD(tree_list);
@@ -2063,7 +2053,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
2063 return PTR_ERR(smp); 2053 return PTR_ERR(smp);
2064 2054
2065 /* Is there space to add these mounts to the mount namespace? */ 2055 /* Is there space to add these mounts to the mount namespace? */
2066 if (!parent_path) { 2056 if (!moving) {
2067 err = count_mounts(ns, source_mnt); 2057 err = count_mounts(ns, source_mnt);
2068 if (err) 2058 if (err)
2069 goto out; 2059 goto out;
@@ -2082,8 +2072,8 @@ static int attach_recursive_mnt(struct mount *source_mnt,
2082 } else { 2072 } else {
2083 lock_mount_hash(); 2073 lock_mount_hash();
2084 } 2074 }
2085 if (parent_path) { 2075 if (moving) {
2086 detach_mnt(source_mnt, parent_path); 2076 unhash_mnt(source_mnt);
2087 attach_mnt(source_mnt, dest_mnt, dest_mp); 2077 attach_mnt(source_mnt, dest_mnt, dest_mp);
2088 touch_mnt_namespace(source_mnt->mnt_ns); 2078 touch_mnt_namespace(source_mnt->mnt_ns);
2089 } else { 2079 } else {
@@ -2181,7 +2171,7 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
2181 d_is_dir(mnt->mnt.mnt_root)) 2171 d_is_dir(mnt->mnt.mnt_root))
2182 return -ENOTDIR; 2172 return -ENOTDIR;
2183 2173
2184 return attach_recursive_mnt(mnt, p, mp, NULL); 2174 return attach_recursive_mnt(mnt, p, mp, false);
2185} 2175}
2186 2176
2187/* 2177/*
@@ -2574,11 +2564,11 @@ out:
2574 2564
2575static int do_move_mount(struct path *old_path, struct path *new_path) 2565static int do_move_mount(struct path *old_path, struct path *new_path)
2576{ 2566{
2577 struct path parent_path = {.mnt = NULL, .dentry = NULL};
2578 struct mnt_namespace *ns; 2567 struct mnt_namespace *ns;
2579 struct mount *p; 2568 struct mount *p;
2580 struct mount *old; 2569 struct mount *old;
2581 struct mountpoint *mp; 2570 struct mount *parent;
2571 struct mountpoint *mp, *old_mp;
2582 int err; 2572 int err;
2583 bool attached; 2573 bool attached;
2584 2574
@@ -2588,7 +2578,9 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
2588 2578
2589 old = real_mount(old_path->mnt); 2579 old = real_mount(old_path->mnt);
2590 p = real_mount(new_path->mnt); 2580 p = real_mount(new_path->mnt);
2581 parent = old->mnt_parent;
2591 attached = mnt_has_parent(old); 2582 attached = mnt_has_parent(old);
2583 old_mp = old->mnt_mp;
2592 ns = old->mnt_ns; 2584 ns = old->mnt_ns;
2593 2585
2594 err = -EINVAL; 2586 err = -EINVAL;
@@ -2616,7 +2608,7 @@ static int do_move_mount(struct path *old_path, struct path *new_path)
2616 /* 2608 /*
2617 * Don't move a mount residing in a shared parent. 2609 * Don't move a mount residing in a shared parent.
2618 */ 2610 */
2619 if (attached && IS_MNT_SHARED(old->mnt_parent)) 2611 if (attached && IS_MNT_SHARED(parent))
2620 goto out; 2612 goto out;
2621 /* 2613 /*
2622 * Don't move a mount tree containing unbindable mounts to a destination 2614 * 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)
2632 goto out; 2624 goto out;
2633 2625
2634 err = attach_recursive_mnt(old, real_mount(new_path->mnt), mp, 2626 err = attach_recursive_mnt(old, real_mount(new_path->mnt), mp,
2635 attached ? &parent_path : NULL); 2627 attached);
2636 if (err) 2628 if (err)
2637 goto out; 2629 goto out;
2638 2630
2639 /* if the mount is moved, it should no longer be expire 2631 /* if the mount is moved, it should no longer be expire
2640 * automatically */ 2632 * automatically */
2641 list_del_init(&old->mnt_expire); 2633 list_del_init(&old->mnt_expire);
2634 if (attached)
2635 put_mountpoint(old_mp);
2642out: 2636out:
2643 unlock_mount(mp); 2637 unlock_mount(mp);
2644 if (!err) { 2638 if (!err) {
2645 path_put(&parent_path); 2639 if (attached)
2646 if (!attached) 2640 mntput_no_expire(parent);
2641 else
2647 free_mnt_ns(ns); 2642 free_mnt_ns(ns);
2648 } 2643 }
2649 return err; 2644 return err;
@@ -3586,8 +3581,8 @@ EXPORT_SYMBOL(path_is_under);
3586SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, 3581SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
3587 const char __user *, put_old) 3582 const char __user *, put_old)
3588{ 3583{
3589 struct path new, old, parent_path, root_parent, root; 3584 struct path new, old, root;
3590 struct mount *new_mnt, *root_mnt, *old_mnt; 3585 struct mount *new_mnt, *root_mnt, *old_mnt, *root_parent, *ex_parent;
3591 struct mountpoint *old_mp, *root_mp; 3586 struct mountpoint *old_mp, *root_mp;
3592 int error; 3587 int error;
3593 3588
@@ -3616,9 +3611,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
3616 new_mnt = real_mount(new.mnt); 3611 new_mnt = real_mount(new.mnt);
3617 root_mnt = real_mount(root.mnt); 3612 root_mnt = real_mount(root.mnt);
3618 old_mnt = real_mount(old.mnt); 3613 old_mnt = real_mount(old.mnt);
3614 ex_parent = new_mnt->mnt_parent;
3615 root_parent = root_mnt->mnt_parent;
3619 if (IS_MNT_SHARED(old_mnt) || 3616 if (IS_MNT_SHARED(old_mnt) ||
3620 IS_MNT_SHARED(new_mnt->mnt_parent) || 3617 IS_MNT_SHARED(ex_parent) ||
3621 IS_MNT_SHARED(root_mnt->mnt_parent)) 3618 IS_MNT_SHARED(root_parent))
3622 goto out4; 3619 goto out4;
3623 if (!check_mnt(root_mnt) || !check_mnt(new_mnt)) 3620 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))
3624 goto out4; 3621 goto out4;
@@ -3635,7 +3632,6 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
3635 goto out4; /* not a mountpoint */ 3632 goto out4; /* not a mountpoint */
3636 if (!mnt_has_parent(root_mnt)) 3633 if (!mnt_has_parent(root_mnt))
3637 goto out4; /* not attached */ 3634 goto out4; /* not attached */
3638 root_mp = root_mnt->mnt_mp;
3639 if (new.mnt->mnt_root != new.dentry) 3635 if (new.mnt->mnt_root != new.dentry)
3640 goto out4; /* not a mountpoint */ 3636 goto out4; /* not a mountpoint */
3641 if (!mnt_has_parent(new_mnt)) 3637 if (!mnt_has_parent(new_mnt))
@@ -3646,10 +3642,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
3646 /* make certain new is below the root */ 3642 /* make certain new is below the root */
3647 if (!is_path_reachable(new_mnt, new.dentry, &root)) 3643 if (!is_path_reachable(new_mnt, new.dentry, &root))
3648 goto out4; 3644 goto out4;
3649 root_mp->m_count++; /* pin it so it won't go away */
3650 lock_mount_hash(); 3645 lock_mount_hash();
3651 detach_mnt(new_mnt, &parent_path); 3646 umount_mnt(new_mnt);
3652 detach_mnt(root_mnt, &root_parent); 3647 root_mp = unhash_mnt(root_mnt); /* we'll need its mountpoint */
3653 if (root_mnt->mnt.mnt_flags & MNT_LOCKED) { 3648 if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {
3654 new_mnt->mnt.mnt_flags |= MNT_LOCKED; 3649 new_mnt->mnt.mnt_flags |= MNT_LOCKED;
3655 root_mnt->mnt.mnt_flags &= ~MNT_LOCKED; 3650 root_mnt->mnt.mnt_flags &= ~MNT_LOCKED;
@@ -3657,7 +3652,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
3657 /* mount old root on put_old */ 3652 /* mount old root on put_old */
3658 attach_mnt(root_mnt, old_mnt, old_mp); 3653 attach_mnt(root_mnt, old_mnt, old_mp);
3659 /* mount new_root on / */ 3654 /* 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);
3661 touch_mnt_namespace(current->nsproxy->mnt_ns); 3657 touch_mnt_namespace(current->nsproxy->mnt_ns);
3662 /* A moved mount should not expire automatically */ 3658 /* A moved mount should not expire automatically */
3663 list_del_init(&new_mnt->mnt_expire); 3659 list_del_init(&new_mnt->mnt_expire);
@@ -3667,10 +3663,8 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
3667 error = 0; 3663 error = 0;
3668out4: 3664out4:
3669 unlock_mount(old_mp); 3665 unlock_mount(old_mp);
3670 if (!error) { 3666 if (!error)
3671 path_put(&root_parent); 3667 mntput_no_expire(ex_parent);
3672 path_put(&parent_path);
3673 }
3674out3: 3668out3:
3675 path_put(&root); 3669 path_put(&root);
3676out2: 3670out2: