Commit 1aba86d6 authored by liubo's avatar liubo Committed by Chris Mason

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: default avatarLiu Bo <liubo2009@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent f5de9391
...@@ -8856,23 +8856,38 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, ...@@ -8856,23 +8856,38 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
int btrfs_init_space_info(struct btrfs_fs_info *fs_info) int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
{ {
struct btrfs_space_info *space_info; struct btrfs_space_info *space_info;
struct btrfs_super_block *disk_super;
u64 features;
u64 flags;
int mixed = 0;
int ret; int ret;
ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, disk_super = &fs_info->super_copy;
&space_info); if (!btrfs_super_root(disk_super))
if (ret) return 1;
return ret;
ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, features = btrfs_super_incompat_flags(disk_super);
&space_info); if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS)
if (ret) mixed = 1;
return ret;
ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, flags = BTRFS_BLOCK_GROUP_SYSTEM;
&space_info); ret = update_space_info(fs_info, flags, 0, 0, &space_info);
if (ret) 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; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment