--- a/fs/btrfs/disk-io.c 2022-03-04 12:03:46.496257700 +0800 +++ b/fs/btrfs/disk-io.c 2022-03-04 12:51:44.296744400 +0800 @@ -3386,7 +3386,9 @@ int __cold open_ctree(struct super_block mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS); btrfs_init_btree_inode(fs_info); - invalidate_bdev(fs_devices->latest_dev->bdev); + err = btrfs_invalidate_bdev(fs_devices); + if (err) + goto fail; /* * Read super block and check the signature bytes only --- a/fs/btrfs/super.c 2022-03-04 11:59:09.105853000 +0800 +++ b/fs/btrfs/super.c 2022-03-04 09:26:58.032689700 +0800 @@ -1644,6 +1644,7 @@ static struct dentry *btrfs_mount_root(s void *new_sec_opts = NULL; fmode_t mode = FMODE_READ; int error = 0; + int closed = 0; if (!(flags & SB_RDONLY)) mode |= FMODE_WRITE; @@ -1712,6 +1713,7 @@ static struct dentry *btrfs_mount_root(s } if (s->s_root) { + closed = 1; btrfs_close_devices(fs_devices); btrfs_free_fs_info(fs_info); if ((flags ^ s->s_flags) & SB_RDONLY) @@ -1727,6 +1729,8 @@ static struct dentry *btrfs_mount_root(s error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL); security_free_mnt_opts(&new_sec_opts); if (error) { + if (!closed) + btrfs_close_devices(fs_devices); deactivate_locked_super(s); return ERR_PTR(error); } --- a/fs/btrfs/volumes.c 2022-03-04 12:04:04.955810600 +0800 +++ b/fs/btrfs/volumes.c 2022-03-04 12:57:48.406739400 +0800 @@ -1105,6 +1105,20 @@ void btrfs_free_extra_devids(struct btrf mutex_unlock(&uuid_mutex); } +int btrfs_invalidate_bdev(struct btrfs_fs_devices *fs_devices) +{ + int err = -ENODEV; + + mutex_lock(&uuid_mutex); + if (fs_devices->latest_dev && + fs_devices->latest_dev->bdev) { + err = 0; + invalidate_bdev(fs_devices->latest_dev->bdev); + } + mutex_unlock(&uuid_mutex); + return err; +} + static void btrfs_close_bdev(struct btrfs_device *device) { if (!device->bdev) --- a/fs/btrfs/volumes.h 2022-03-04 12:04:04.977142800 +0800 +++ b/fs/btrfs/volumes.h 2022-03-04 12:58:19.290341100 +0800 @@ -508,6 +508,7 @@ struct btrfs_device *btrfs_scan_one_devi int btrfs_forget_devices(const char *path); void btrfs_close_devices(struct btrfs_fs_devices *fs_devices); void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices); +int btrfs_invalidate_bdev(struct btrfs_fs_devices *fs_devices); void btrfs_assign_next_active_device(struct btrfs_device *device, struct btrfs_device *this_dev); struct btrfs_device *btrfs_find_device_by_devspec(struct btrfs_fs_info *fs_info,