Skip to content

Commit 96f5d2e

Browse files
author
Al Viro
committed
attach_recursive_mnt(): unify the mnt_change_mountpoint() logics
The logics used for tucking under existing mount differs for original and copies; copies do a mount hash lookup to see if mountpoint to be is already overmounted, while the original is told explicitly. But the same logics that is used for copies works for the original, at which point the only place where we get very close to eliminating the need of passing 'beneath' flag to attach_recursive_mnt(). Signed-off-by: Al Viro <[email protected]>
1 parent 7c6fb47 commit 96f5d2e

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

fs/namespace.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2643,7 +2643,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
26432643
HLIST_HEAD(tree_list);
26442644
struct mnt_namespace *ns = top_mnt->mnt_ns;
26452645
struct mountpoint *smp;
2646-
struct mountpoint *secondary = NULL;
2646+
struct mountpoint *shorter = NULL;
26472647
struct mount *child, *dest_mnt, *p;
26482648
struct mount *top;
26492649
struct hlist_node *n;
@@ -2655,14 +2655,12 @@ static int attach_recursive_mnt(struct mount *source_mnt,
26552655
* mounted beneath mounts on the same mountpoint.
26562656
*/
26572657
for (top = source_mnt; unlikely(top->overmount); top = top->overmount) {
2658-
if (!secondary && is_mnt_ns_file(top->mnt.mnt_root))
2659-
secondary = top->mnt_mp;
2658+
if (!shorter && is_mnt_ns_file(top->mnt.mnt_root))
2659+
shorter = top->mnt_mp;
26602660
}
26612661
smp = get_mountpoint(top->mnt.mnt_root);
26622662
if (IS_ERR(smp))
26632663
return PTR_ERR(smp);
2664-
if (!secondary)
2665-
secondary = smp;
26662664

26672665
/* Is there space to add these mounts to the mount namespace? */
26682666
if (!moving) {
@@ -2706,9 +2704,14 @@ static int attach_recursive_mnt(struct mount *source_mnt,
27062704
}
27072705

27082706
mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
2709-
if (beneath)
2710-
mnt_change_mountpoint(top, smp, top_mnt);
2711-
commit_tree(source_mnt);
2707+
/*
2708+
* Now the original copy is in the same state as the secondaries -
2709+
* its root attached to mountpoint, but not hashed and all mounts
2710+
* in it are either in our namespace or in no namespace at all.
2711+
* Add the original to the list of copies and deal with the
2712+
* rest of work for all of them uniformly.
2713+
*/
2714+
hlist_add_head(&source_mnt->mnt_hash, &tree_list);
27122715

27132716
hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) {
27142717
struct mount *q;
@@ -2719,10 +2722,13 @@ static int attach_recursive_mnt(struct mount *source_mnt,
27192722
q = __lookup_mnt(&child->mnt_parent->mnt,
27202723
child->mnt_mountpoint);
27212724
if (q) {
2725+
struct mountpoint *mp = smp;
27222726
struct mount *r = child;
27232727
while (unlikely(r->overmount))
27242728
r = r->overmount;
2725-
mnt_change_mountpoint(r, secondary, q);
2729+
if (unlikely(shorter) && child != source_mnt)
2730+
mp = shorter;
2731+
mnt_change_mountpoint(r, mp, q);
27262732
}
27272733
commit_tree(child);
27282734
}

0 commit comments

Comments
 (0)