diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2025-08-19 12:22:03 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2025-09-15 21:26:44 -0400 |
| commit | 75db7fd99075bf46f3bfeaa8f1aaa8b13b2590cf (patch) | |
| tree | 3576689e6874a7773f06685c151997d9c0f08434 /fs/namespace.c | |
| parent | fc9d5efc4c620807af53d62285adc7d4bf9b9978 (diff) | |
umount_tree(): take all victims out of propagation graph at once
For each removed mount we need to calculate where the slaves will end up.
To avoid duplicating that work, do it for all mounts to be removed
at once, taking the mounts themselves out of propagation graph as
we go, then do all transfers; the duplicate work on finding destinations
is avoided since if we run into a mount that already had destination found,
we don't need to trace the rest of the way. That's guaranteed
O(removed mounts) for finding destinations and removing from propagation
graph and O(surviving mounts that have master removed) for transfers.
Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namespace.c')
| -rw-r--r-- | fs/namespace.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 75856c7ce746..ae29cbf13e39 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1846,6 +1846,8 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) if (how & UMOUNT_PROPAGATE) propagate_umount(&tmp_list); + bulk_make_private(&tmp_list); + while (!list_empty(&tmp_list)) { struct mnt_namespace *ns; bool disconnect; @@ -1870,7 +1872,6 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) umount_mnt(p); } } - change_mnt_propagation(p, MS_PRIVATE); if (disconnect) hlist_add_head(&p->mnt_umount, &unmounted); |