Skip to content

Commit

Permalink
Btrfs: fix easily get into ENOSPC in mixed case
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Chris Mason <[email protected]>
  • Loading branch information
liub authored and chrismason-xx committed May 14, 2011
1 parent f5de939 commit 1aba86d
Showing 1 changed file with 26 additions and 11 deletions.
37 changes: 26 additions & 11 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
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;
}

Expand Down

0 comments on commit 1aba86d

Please sign in to comment.