summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2025-08-14 23:32:26 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2025-08-19 12:00:07 -0400
commitda025cdb97a23c1916d8491925b878f3e1de0bca (patch)
tree63cec32b7b9a1211bc67df47e6837f556fc87828
parent0ddfb62f5d018edcb571a3d8ea30ad5332cf2a69 (diff)
propagate_umount(): only surviving overmounts should be reparented
... as the comments in reparent() clearly say. As it is, we reparent *all* overmounts of the mounts being taken out, including those that are taken out themselves. It's not only a potentially massive slowdown (on a pathological setup we might end up with O(N^2) time for N mounts being kicked out), it can end up with incorrect ->overmount in the surviving mounts. Fixes: f0d0ba19985d "Rewrite of propagate_umount()" Reviewed-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/pnode.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/pnode.c b/fs/pnode.c
index 81f7599bdac4..1c789f88b3d2 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -637,10 +637,11 @@ void propagate_umount(struct list_head *set)
}
// now to_umount consists of all acceptable candidates
- // deal with reparenting of remaining overmounts on those
+ // deal with reparenting of surviving overmounts on those
list_for_each_entry(m, &to_umount, mnt_list) {
- if (m->overmount)
- reparent(m->overmount);
+ struct mount *over = m->overmount;
+ if (over && !will_be_unmounted(over))
+ reparent(over);
}
// and fold them into the set