From f0efbf1e36f30180b75a90d3f9c82bdc8c3dba7a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 24 Jul 2019 12:45:46 -0400 Subject: [PATCH] fix the struct mount leak in umount_tree() We need to drop everything we remove from the tree, whether mnt_has_parent() is true or not. Usually the bug manifests as a slow memory leak (leaked struct mount for initramfs); it becomes much more visible in mount_subtree() users, such as btrfs. There we leak a struct mount for btrfs superblock being mounted, which prevents fs shutdown on subsequent umount. Fixes: ac1afdbb601b ("switch the remnants of releasing the mountpoint away from fs_pin") Reported-by: Nikolay Borisov Tested-by: Nikolay Borisov Signed-off-by: Al Viro --- fs/namespace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 6464ea4acba94..d28d30b130439 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1463,7 +1463,6 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) p->mnt.mnt_flags |= MNT_SYNC_UMOUNT; disconnect = disconnect_mount(p, how); - if (mnt_has_parent(p)) { mnt_add_count(p->mnt_parent, -1); if (!disconnect) { @@ -1471,10 +1470,11 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how) list_add_tail(&p->mnt_child, &p->mnt_parent->mnt_mounts); } else { umount_mnt(p); - hlist_add_head(&p->mnt_umount, &unmounted); } } change_mnt_propagation(p, MS_PRIVATE); + if (disconnect) + hlist_add_head(&p->mnt_umount, &unmounted); } } -- 2.39.5