--- a/fs/btrfs/ctree.h 2022-03-04 18:35:29.677440700 +0800 +++ b/fs/btrfs/ctree.h 2022-03-04 18:40:13.673766400 +0800 @@ -851,6 +851,7 @@ struct btrfs_fs_info { struct btrfs_fs_devices *fs_devices; + struct completion serialize_fs_devices; /* * The space_info list is effectively read only after initial * setup. It is populated at mount time and cleaned up after --- a/fs/btrfs/super.c 2022-03-04 11:59:09.105853000 +0800 +++ b/fs/btrfs/super.c 2022-03-04 19:00:49.983897700 +0800 @@ -1667,6 +1667,7 @@ static struct dentry *btrfs_mount_root(s error = -ENOMEM; goto error_sec_opts; } + init_completion(&fs_info->serialize_fs_devices); btrfs_init_fs_info(fs_info); fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); @@ -2342,7 +2343,17 @@ static int btrfs_statfs(struct dentry *d static void btrfs_kill_super(struct super_block *sb) { struct btrfs_fs_info *fs_info = btrfs_sb(sb); + bool wait = false; + kill_anon_super(sb); + + mutex_lock(&uuid_mutex); + wait = fs_info->fs_devices && + fs_info->fs_devices->fs_info == fs_info; + mutex_unlock(&uuid_mutex); + if (wait) + wait_for_completion(&fs_info->serialize_fs_devices); + btrfs_free_fs_info(fs_info); } --- a/fs/btrfs/volumes.c 2022-03-04 12:04:04.955810600 +0800 +++ b/fs/btrfs/volumes.c 2022-03-04 19:37:28.783612100 +0800 @@ -1191,17 +1191,23 @@ void btrfs_close_devices(struct btrfs_fs { LIST_HEAD(list); struct btrfs_fs_devices *tmp; + struct btrfs_fs_info *fs_info; mutex_lock(&uuid_mutex); + fs_info = fs_devices->fs_info; close_fs_devices(fs_devices); if (!fs_devices->opened) list_splice_init(&fs_devices->seed_list, &list); + else + fs_info = NULL; list_for_each_entry_safe(fs_devices, tmp, &list, seed_list) { close_fs_devices(fs_devices); list_del(&fs_devices->seed_list); free_fs_devices(fs_devices); } + if (fs_info) + complete(&fs_info->serialize_fs_devices); mutex_unlock(&uuid_mutex); }