Btrfs: fix easily get into ENOSPC in mixed case
When a btrfs disk is created by mixed data & metadata option, it will have no pure data or pure metadata space info. In btrfs's for-linus branch, commit 78b1ea13838039cd88afdd62519b40b344d6c920 (Btrfs: fix OOPS of empty filesystem after balance) initializes space infos at the very beginning. The problem is this initialization does not take the mixed case into account, which will cause btrfs will easily get into ENOSPC in mixed case. Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
f5de939149
commit
1aba86d67f
|
@ -8856,23 +8856,38 @@ out:
|
|||
int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
|
||||
{
|
||||
struct btrfs_space_info *space_info;
|
||||
struct btrfs_super_block *disk_super;
|
||||
u64 features;
|
||||
u64 flags;
|
||||
int mixed = 0;
|
||||
int ret;
|
||||
|
||||
ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0,
|
||||
&space_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
disk_super = &fs_info->super_copy;
|
||||
if (!btrfs_super_root(disk_super))
|
||||
return 1;
|
||||
|
||||
ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0,
|
||||
&space_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
features = btrfs_super_incompat_flags(disk_super);
|
||||
if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
|
||||
mixed = 1;
|
||||
|
||||
ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0,
|
||||
&space_info);
|
||||
flags = BTRFS_BLOCK_GROUP_SYSTEM;
|
||||
ret = update_space_info(fs_info, flags, 0, 0, &space_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
if (mixed) {
|
||||
flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA;
|
||||
ret = update_space_info(fs_info, flags, 0, 0, &space_info);
|
||||
} else {
|
||||
flags = BTRFS_BLOCK_GROUP_METADATA;
|
||||
ret = update_space_info(fs_info, flags, 0, 0, &space_info);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
flags = BTRFS_BLOCK_GROUP_DATA;
|
||||
ret = update_space_info(fs_info, flags, 0, 0, &space_info);
|
||||
}
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue