Skip to content

Commit 7c6fb47

Browse files
author
Al Viro
committed
make commit_tree() usable in same-namespace move case
Once attach_recursive_mnt() has created all copies of original subtree, it needs to put them in place(s). Steps needed for those are slightly different: 1) in 'move' case, original copy doesn't need any rbtree manipulations (everything's already in the same namespace where it will be), but it needs to be detached from the current location 2) in 'attach' case, original may be in anon namespace; if it is, all those mounts need to removed from their current namespace before insertion into the target one 3) additional copies have a couple of extra twists - in case of cross-userns propagation we need to lock everything other the root of subtree and in case when we end up inserting under an existing mount, that mount needs to be found (for original copy we have it explicitly passed by the caller). Quite a bit of that can be unified; as the first step, make commit_tree() helper (inserting mounts into namespace, hashing the root of subtree and marking the namespace as updated) usable in all cases; (2) and (3) are already using it and for (1) we only need to make the insertion of mounts into namespace conditional. Signed-off-by: Al Viro <[email protected]>
1 parent f0d0ba1 commit 7c6fb47

File tree

1 file changed

+14
-16
lines changed

1 file changed

+14
-16
lines changed

fs/namespace.c

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,15 +1172,17 @@ static void commit_tree(struct mount *mnt)
11721172

11731173
BUG_ON(parent == mnt);
11741174

1175-
list_add_tail(&head, &mnt->mnt_list);
1176-
while (!list_empty(&head)) {
1177-
m = list_first_entry(&head, typeof(*m), mnt_list);
1178-
list_del(&m->mnt_list);
1175+
if (!mnt_ns_attached(mnt)) {
1176+
list_add_tail(&head, &mnt->mnt_list);
1177+
while (!list_empty(&head)) {
1178+
m = list_first_entry(&head, typeof(*m), mnt_list);
1179+
list_del(&m->mnt_list);
11791180

1180-
mnt_add_to_ns(n, m);
1181+
mnt_add_to_ns(n, m);
1182+
}
1183+
n->nr_mounts += n->pending_mounts;
1184+
n->pending_mounts = 0;
11811185
}
1182-
n->nr_mounts += n->pending_mounts;
1183-
n->pending_mounts = 0;
11841186

11851187
make_visible(mnt);
11861188
touch_mnt_namespace(n);
@@ -2691,12 +2693,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
26912693

26922694
if (moving) {
26932695
unhash_mnt(source_mnt);
2694-
mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
2695-
if (beneath)
2696-
mnt_change_mountpoint(top, smp, top_mnt);
2697-
make_visible(source_mnt);
26982696
mnt_notify_add(source_mnt);
2699-
touch_mnt_namespace(source_mnt->mnt_ns);
27002697
} else {
27012698
if (source_mnt->mnt_ns) {
27022699
LIST_HEAD(head);
@@ -2706,12 +2703,13 @@ static int attach_recursive_mnt(struct mount *source_mnt,
27062703
move_from_ns(p, &head);
27072704
list_del_init(&head);
27082705
}
2709-
mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
2710-
if (beneath)
2711-
mnt_change_mountpoint(top, smp, top_mnt);
2712-
commit_tree(source_mnt);
27132706
}
27142707

2708+
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);
2712+
27152713
hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) {
27162714
struct mount *q;
27172715
hlist_del_init(&child->mnt_hash);

0 commit comments

Comments
 (0)