mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
btrfs: call btrfs_close_devices() from ->kill_sb
Although btrfs is not yet implementing blk_holder_ops, there is a requirement for proper blk_holder_ops: - blkdev_put() must not be called under sb->s_umount The blkdev_put()/bdev_fput() must not be called under sb->s_umount to avoid lock order reversal with disk->open_mutex. This is for the proper blk_holder_ops callbacks. Currently we're fine because we call regular fput() which defers the blk holder reclaiming. To prepare for the future of blk_holder_ops, move the btrfs_close_devices() calls into btrfs_free_fs_info(). That will be called from kill_sb() callbacks, which is also called for error handing during mount failures, or there is already an existing super block. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
2936a6ac8d
commit
9f43d0ff55
|
|
@ -1246,6 +1246,8 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
|
|||
{
|
||||
struct percpu_counter *em_counter = &fs_info->evictable_extent_maps;
|
||||
|
||||
if (fs_info->fs_devices)
|
||||
btrfs_close_devices(fs_info->fs_devices);
|
||||
percpu_counter_destroy(&fs_info->stats_read_blocks);
|
||||
percpu_counter_destroy(&fs_info->dirty_metadata_bytes);
|
||||
percpu_counter_destroy(&fs_info->delalloc_bytes);
|
||||
|
|
@ -3681,7 +3683,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;
|
||||
}
|
||||
|
|
@ -4428,7 +4429,6 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info)
|
|||
iput(fs_info->btree_inode);
|
||||
|
||||
btrfs_mapping_tree_free(fs_info);
|
||||
btrfs_close_devices(fs_info->fs_devices);
|
||||
}
|
||||
|
||||
void btrfs_mark_buffer_dirty(struct btrfs_trans_handle *trans,
|
||||
|
|
|
|||
|
|
@ -1869,18 +1869,14 @@ static int btrfs_get_tree_super(struct fs_context *fc)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(fc->sb_flags & SB_RDONLY) && fs_devices->rw_devices == 0) {
|
||||
ret = -EACCES;
|
||||
goto error;
|
||||
}
|
||||
if (!(fc->sb_flags & SB_RDONLY) && fs_devices->rw_devices == 0)
|
||||
return -EACCES;
|
||||
|
||||
bdev = fs_devices->latest_dev->bdev;
|
||||
|
||||
sb = sget_fc(fc, btrfs_fc_test_super, set_anon_super_fc);
|
||||
if (IS_ERR(sb)) {
|
||||
ret = PTR_ERR(sb);
|
||||
goto error;
|
||||
}
|
||||
if (IS_ERR(sb))
|
||||
return PTR_ERR(sb);
|
||||
|
||||
set_device_specific_options(fs_info);
|
||||
|
||||
|
|
@ -1888,17 +1884,14 @@ static int btrfs_get_tree_super(struct fs_context *fc)
|
|||
/*
|
||||
* Not the first mount of the fs thus got an existing super block.
|
||||
* Will reuse the returned super block, fs_info and fs_devices.
|
||||
*/
|
||||
ASSERT(fc->s_fs_info == fs_info);
|
||||
|
||||
/*
|
||||
*
|
||||
* fc->s_fs_info is not touched and will be later freed by
|
||||
* put_fs_context() through btrfs_free_fs_context().
|
||||
*
|
||||
* But we have opened fs_devices at the beginning of the
|
||||
* function, thus still need to close them manually.
|
||||
* The fs_info->fs_devices will also be closed by btrfs_free_fs_context().
|
||||
*/
|
||||
btrfs_close_devices(fs_devices);
|
||||
ASSERT(fc->s_fs_info == fs_info);
|
||||
|
||||
/*
|
||||
* At this stage we may have RO flag mismatch between
|
||||
* fc->sb_flags and sb->s_flags. Caller should detect such
|
||||
|
|
@ -1927,10 +1920,6 @@ static int btrfs_get_tree_super(struct fs_context *fc)
|
|||
|
||||
fc->root = dget(sb->s_root);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
btrfs_close_devices(fs_devices);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user