HLIST_HEAD(tree_list);
struct mnt_namespace *ns = top_mnt->mnt_ns;
struct mountpoint *smp;
- struct mountpoint *secondary = NULL;
+ struct mountpoint *shorter = NULL;
struct mount *child, *dest_mnt, *p;
struct mount *top;
struct hlist_node *n;
* mounted beneath mounts on the same mountpoint.
*/
for (top = source_mnt; unlikely(top->overmount); top = top->overmount) {
- if (!secondary && is_mnt_ns_file(top->mnt.mnt_root))
- secondary = top->mnt_mp;
+ if (!shorter && is_mnt_ns_file(top->mnt.mnt_root))
+ shorter = top->mnt_mp;
}
smp = get_mountpoint(top->mnt.mnt_root);
if (IS_ERR(smp))
return PTR_ERR(smp);
- if (!secondary)
- secondary = smp;
/* Is there space to add these mounts to the mount namespace? */
if (!moving) {
}
mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
- if (beneath)
- mnt_change_mountpoint(top, smp, top_mnt);
- commit_tree(source_mnt);
+ /*
+ * Now the original copy is in the same state as the secondaries -
+ * its root attached to mountpoint, but not hashed and all mounts
+ * in it are either in our namespace or in no namespace at all.
+ * Add the original to the list of copies and deal with the
+ * rest of work for all of them uniformly.
+ */
+ hlist_add_head(&source_mnt->mnt_hash, &tree_list);
hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) {
struct mount *q;
q = __lookup_mnt(&child->mnt_parent->mnt,
child->mnt_mountpoint);
if (q) {
+ struct mountpoint *mp = smp;
struct mount *r = child;
while (unlikely(r->overmount))
r = r->overmount;
- mnt_change_mountpoint(r, secondary, q);
+ if (unlikely(shorter) && child != source_mnt)
+ mp = shorter;
+ mnt_change_mountpoint(r, mp, q);
}
commit_tree(child);
}