summaryrefslogtreecommitdiff
path: root/extent-tree.c
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-05-05 16:16:12 +0200
committerChris Mason <chris.mason@oracle.com>2011-10-25 09:18:58 -0400
commit2689259501c1a52a95c934f464460ed362bc0489 (patch)
tree7781b1b914ad7cbdb4b2c3f19de650fdba81adff /extent-tree.c
parentde07f367c4fa42e257e8a04eb0637a54825b3a9a (diff)
btrfs progs: fix extra metadata chunk allocation in --mixed case
When creating a mixed fs with mkfs, an extra metadata chunk got allocated. This is because btrfs_reserve_extent calls do_chunk_alloc for METADATA, which in turn wasn't able to find the proper space_info, as __find_space_info did a hard compare of the flags. It is now sufficient for the space_info to include the proper flag. This reflects the change done to the kernel code to support mixed chunks. Also for a subsequent chunk allocation (which should not be hit in the mkfs case), the chunk is now created with the flags from the space_info instead of the requested flags. A better solution would be to pull the full changeset for the mixed case from the kernel into the user mode (or, even better, share the code) The additional chunk probably confused block_rsv calculation, which in turn led to severeal ENOSPC Oopses. Signed-off-by: Arne Jansen <sensille@gmx.net> Signed-off-by: Hugo Mills <hugo@carfax.org.uk>
Diffstat (limited to 'extent-tree.c')
-rw-r--r--extent-tree.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/extent-tree.c b/extent-tree.c
index 88c67d6f..b5b7aaa5 100644
--- a/extent-tree.c
+++ b/extent-tree.c
@@ -1706,7 +1706,7 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info,
struct btrfs_space_info *found;
list_for_each(cur, head) {
found = list_entry(cur, struct btrfs_space_info, list);
- if (found->flags == flags)
+ if (found->flags & flags)
return found;
}
return NULL;
@@ -1784,7 +1784,8 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
thresh)
return 0;
- ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags);
+ ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes,
+ space_info->flags);
if (ret == -ENOSPC) {
space_info->full = 1;
return 0;
@@ -1792,7 +1793,7 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
BUG_ON(ret);
- ret = btrfs_make_block_group(trans, extent_root, 0, flags,
+ ret = btrfs_make_block_group(trans, extent_root, 0, space_info->flags,
BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes);
BUG_ON(ret);
return 0;