Message ID | 1472173707-4533-1-git-send-email-bo.li.liu@oracle.com (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
On Thu, Aug 25, 2016 at 06:08:27PM -0700, Liu Bo wrote: > Currently we allow inconsistence about mixed flag > (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA). > > We'd get ENOSPC if block group has mixed flag and btrfs doesn't. > If that happens, we have one space_info with mixed flag and another > space_info only with BTRFS_BLOCK_GROUP_METADATA, and > global_block_rsv.space_info points to the latter one, but all bytes > from block_group contributes to the mixed space_info, thus all the > allocation will fail with ENOSPC. > > This adds a check for the above case. > > Reported-by: Vegard Nossum <vegard.nossum@oracle.com> > Signed-off-by: Liu Bo <bo.li.liu@oracle.com> OK for the fix. Even if we allow combining mixed and split bg, the incompat bit must be present. This could be also part of fsck, as we don't give an option how to fix that. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 806921f..642e0f0 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -10150,6 +10150,11 @@ int btrfs_read_block_groups(struct btrfs_root *root) struct extent_buffer *leaf; int need_clear = 0; u64 cache_gen; + u64 feature; + int mixed; + + feature = btrfs_super_incompat_flags(info->super_copy); + mixed = !!(feature & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS); root = info->extent_root; key.objectid = 0; @@ -10203,6 +10208,15 @@ int btrfs_read_block_groups(struct btrfs_root *root) btrfs_item_ptr_offset(leaf, path->slots[0]), sizeof(cache->item)); cache->flags = btrfs_block_group_flags(&cache->item); + if (!mixed && + ((cache->flags & BTRFS_BLOCK_GROUP_METADATA) && + (cache->flags & BTRFS_BLOCK_GROUP_DATA))) { + btrfs_err(info, + "bg(%llu) is a mixed block group but this is not a mixed btrfs image.", + cache->key.objectid); + ret = -EINVAL; + goto error; + } key.objectid = found_key.objectid + found_key.offset; btrfs_release_path(path);
Currently we allow inconsistence about mixed flag (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA). We'd get ENOSPC if block group has mixed flag and btrfs doesn't. If that happens, we have one space_info with mixed flag and another space_info only with BTRFS_BLOCK_GROUP_METADATA, and global_block_rsv.space_info points to the latter one, but all bytes from block_group contributes to the mixed space_info, thus all the allocation will fail with ENOSPC. This adds a check for the above case. Reported-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Liu Bo <bo.li.liu@oracle.com> --- fs/btrfs/extent-tree.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)