mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
fix the softlockups in attach_recursive_mnt()
In case when we mounting something on top of a large stack of overmounts,
all of them being peers of each other, we get quadratic time by the
depth of overmount stack. Easily fixed by doing commit_tree() before
reparenting the overmount; simplifies commit_tree() as well - it doesn't
need to skip the already mounted stuff that had been reparented on top
of the new mounts.
Since we are holding mount_lock through both reparenting and call of
commit_tree(), the order does not matter from the mount hash point
of view.
Reported-by: "Lai, Yi" <yi1.lai@linux.intel.com>
Tested-by: "Lai, Yi" <yi1.lai@linux.intel.com>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Fixes: 663206854f "copy_tree(): don't link the mounts via mnt_list"
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
8742b2d893
commit
0ddfb62f5d
|
|
@ -1197,10 +1197,7 @@ static void commit_tree(struct mount *mnt)
|
|||
|
||||
if (!mnt_ns_attached(mnt)) {
|
||||
for (struct mount *m = mnt; m; m = next_mnt(m, mnt))
|
||||
if (unlikely(mnt_ns_attached(m)))
|
||||
m = skip_mnt_tree(m);
|
||||
else
|
||||
mnt_add_to_ns(n, m);
|
||||
mnt_add_to_ns(n, m);
|
||||
n->nr_mounts += n->pending_mounts;
|
||||
n->pending_mounts = 0;
|
||||
}
|
||||
|
|
@ -2704,6 +2701,7 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
|||
lock_mnt_tree(child);
|
||||
q = __lookup_mnt(&child->mnt_parent->mnt,
|
||||
child->mnt_mountpoint);
|
||||
commit_tree(child);
|
||||
if (q) {
|
||||
struct mountpoint *mp = root.mp;
|
||||
struct mount *r = child;
|
||||
|
|
@ -2713,7 +2711,6 @@ static int attach_recursive_mnt(struct mount *source_mnt,
|
|||
mp = shorter;
|
||||
mnt_change_mountpoint(r, mp, q);
|
||||
}
|
||||
commit_tree(child);
|
||||
}
|
||||
unpin_mountpoint(&root);
|
||||
unlock_mount_hash();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user