mirror of
https://github.com/torvalds/linux.git
synced 2026-06-02 11:33:28 +02:00
btrfs: add assertions to make super block creation more clear
When calling sget_fc(), there are 3 different situations: a) Critical error No super block created. b) A new super block is created The fc->s_fs_info is transferred to the super block, and fc->s_fs_info is reset to NULL. In this case sb->s_root should still be NULL, and needs to be properly initialized later by btrfs_fill_super(). c) An existing super block is returned The fc->s_fs_info is untouched, and anything related to that fs_info should be properly cleaned up. This is not obvious even with the extra comments at sget_fc(). Enhance the situation by: - Add comments for case b) and c) Especially for case c), the fs_info and fs_devices cleanup happens at different timing, thus needs extra explanation. - Move the comments closer to case b) and case c) Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
35ea448b75
commit
2936a6ac8d
|
|
@ -1876,15 +1876,6 @@ static int btrfs_get_tree_super(struct fs_context *fc)
|
|||
|
||||
bdev = fs_devices->latest_dev->bdev;
|
||||
|
||||
/*
|
||||
* From now on the error handling is not straightforward.
|
||||
*
|
||||
* If successful, this will transfer the fs_info into the super block,
|
||||
* and fc->s_fs_info will be NULL. However if there's an existing
|
||||
* super, we'll still have fc->s_fs_info populated. If we error
|
||||
* completely out it'll be cleaned up when we drop the fs_context,
|
||||
* otherwise it's tied to the lifetime of the super_block.
|
||||
*/
|
||||
sb = sget_fc(fc, btrfs_fc_test_super, set_anon_super_fc);
|
||||
if (IS_ERR(sb)) {
|
||||
ret = PTR_ERR(sb);
|
||||
|
|
@ -1894,6 +1885,19 @@ static int btrfs_get_tree_super(struct fs_context *fc)
|
|||
set_device_specific_options(fs_info);
|
||||
|
||||
if (sb->s_root) {
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
btrfs_close_devices(fs_devices);
|
||||
/*
|
||||
* At this stage we may have RO flag mismatch between
|
||||
|
|
@ -1902,6 +1906,13 @@ static int btrfs_get_tree_super(struct fs_context *fc)
|
|||
* needed.
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* The first mount of the fs thus a new superblock, fc->s_fs_info
|
||||
* must be NULL, and the ownership of our fs_info and fs_devices is
|
||||
* transferred to the super block.
|
||||
*/
|
||||
ASSERT(fc->s_fs_info == NULL);
|
||||
|
||||
snprintf(sb->s_id, sizeof(sb->s_id), "%pg", bdev);
|
||||
shrinker_debugfs_rename(sb->s_shrink, "sb-btrfs:%s", sb->s_id);
|
||||
btrfs_sb(sb)->bdev_holder = &btrfs_fs_type;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user