blkdev_put must not be called under sb->s_umount to avoid a lock order reversal with disk->open_mutex once call backs from block devices to the file system using the holder ops are supported. Move the call to btrfs_close_devices into btrfs_free_fs_info so that it is closed from ->kill_sb (which is also called from the mount failure handling path unlike ->put_super) as well as when an fs_info is freed because an existing superblock already exists. Signed-off-by: Christoph Hellwig <hch@xxxxxx> --- fs/btrfs/disk-io.c | 4 ++-- fs/btrfs/super.c | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7513388b0567be..3788b55638392e 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1243,6 +1243,8 @@ static void free_global_roots(struct btrfs_fs_info *fs_info) void btrfs_free_fs_info(struct btrfs_fs_info *fs_info) { + if (fs_info->fs_devices) + btrfs_close_devices(fs_info->fs_devices); percpu_counter_destroy(&fs_info->dirty_metadata_bytes); percpu_counter_destroy(&fs_info->delalloc_bytes); percpu_counter_destroy(&fs_info->ordered_bytes); @@ -3554,7 +3556,6 @@ int __cold open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_device iput(fs_info->btree_inode); fail: - btrfs_close_devices(fs_info->fs_devices); ASSERT(ret < 0); return ret; } @@ -4408,7 +4409,6 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) #endif btrfs_mapping_tree_free(&fs_info->mapping_tree); - btrfs_close_devices(fs_info->fs_devices); } void btrfs_mark_buffer_dirty(struct extent_buffer *buf) diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b318bddefd5236..2bbc041ac2e2c5 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1494,7 +1494,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, if (!(flags & SB_RDONLY) && fs_devices->rw_devices == 0) { error = -EACCES; - goto error_close_devices; + goto error_fs_info; } bdev = fs_devices->latest_dev->bdev; @@ -1502,11 +1502,10 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, fs_info); if (IS_ERR(s)) { error = PTR_ERR(s); - goto error_close_devices; + goto error_fs_info; } if (s->s_root) { - btrfs_close_devices(fs_devices); btrfs_free_fs_info(fs_info); if ((flags ^ s->s_flags) & SB_RDONLY) error = -EBUSY; @@ -1527,8 +1526,6 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type, return dget(s->s_root); -error_close_devices: - btrfs_close_devices(fs_devices); error_fs_info: btrfs_free_fs_info(fs_info); error_sec_opts: -- 2.39.2