@@ -1182,6 +1182,8 @@ struct btrfs_block_group {
*/
u64 alloc_offset;
u64 write_offset;
+
+ u64 global_root_id;
};
struct btrfs_device;
@@ -787,13 +787,33 @@ struct btrfs_root *btrfs_global_root(struct btrfs_fs_info *fs_info,
return NULL;
}
+u64 btrfs_global_root_id(struct btrfs_fs_info *fs_info, u64 bytenr)
+{
+ struct btrfs_block_group *block_group;
+ u64 ret = 0;
+
+ if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+ return ret;
+
+ /*
+ * We use this because we won't have this many global roots, and -1 is
+ * special, so we need something that'll not be found if we have any
+ * errors from here on.
+ */
+ ret = BTRFS_LAST_FREE_OBJECTID;
+ block_group = btrfs_lookup_first_block_group(fs_info, bytenr);
+ if (block_group)
+ ret = block_group->global_root_id;
+ return ret;
+}
+
struct btrfs_root *btrfs_csum_root(struct btrfs_fs_info *fs_info,
u64 bytenr)
{
struct btrfs_key key = {
.objectid = BTRFS_CSUM_TREE_OBJECTID,
.type = BTRFS_ROOT_ITEM_KEY,
- .offset = 0,
+ .offset = btrfs_global_root_id(fs_info, bytenr),
};
return btrfs_global_root(fs_info, &key);
@@ -805,7 +825,7 @@ struct btrfs_root *btrfs_extent_root(struct btrfs_fs_info *fs_info,
struct btrfs_key key = {
.objectid = BTRFS_EXTENT_TREE_OBJECTID,
.type = BTRFS_ROOT_ITEM_KEY,
- .offset = 0,
+ .offset = btrfs_global_root_id(fs_info, bytenr),
};
return btrfs_global_root(fs_info, &key);
@@ -221,6 +221,7 @@ struct btrfs_root *btrfs_csum_root(struct btrfs_fs_info *fs_info, u64 bytenr);
struct btrfs_root *btrfs_extent_root(struct btrfs_fs_info *fs_inf, u64 bytenr);
struct btrfs_root *btrfs_global_root(struct btrfs_fs_info *fs_info,
struct btrfs_key *key);
+u64 btrfs_global_root_id(struct btrfs_fs_info *fs_info, u64 bytenr);
int btrfs_global_root_insert(struct btrfs_fs_info *fs_info,
struct btrfs_root *root);
@@ -1561,7 +1561,7 @@ static int update_block_group_item(struct btrfs_trans_handle *trans,
btrfs_set_stack_block_group_used(&bgi, cache->used);
btrfs_set_stack_block_group_flags(&bgi, cache->flags);
btrfs_set_stack_block_group_chunk_objectid(&bgi,
- BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+ cache->global_root_id);
write_extent_buffer(leaf, &bgi, bi, sizeof(bgi));
btrfs_mark_buffer_dirty(leaf);
fail:
@@ -2658,6 +2658,7 @@ static int read_block_group_item(struct btrfs_block_group *cache,
sizeof(bgi));
cache->used = btrfs_stack_block_group_used(&bgi);
cache->flags = btrfs_stack_block_group_flags(&bgi);
+ cache->global_root_id = btrfs_stack_block_group_chunk_objectid(&bgi);
return 0;
}
@@ -2777,6 +2778,18 @@ btrfs_add_block_group(struct btrfs_fs_info *fs_info, u64 bytes_used, u64 type,
cache->start = chunk_offset;
cache->length = size;
+ /*
+ * If we have extent tree v2 set then set it to the next global root id
+ * based on our offset. Otherwise set it to
+ * BTRFS_FIRST_CHUNK_TREE_OBJECTID so that extent tree v1 has the
+ * appropriate setting.
+ */
+ if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+ cache->global_root_id = div_u64(chunk_offset, SZ_1G) %
+ fs_info->num_global_roots;
+ else
+ cache->global_root_id = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
+
ret = btrfs_load_block_group_zone_info(fs_info, cache);
BUG_ON(ret);
@@ -2806,7 +2819,7 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
btrfs_set_stack_block_group_used(&bgi, block_group->used);
btrfs_set_stack_block_group_chunk_objectid(&bgi,
- BTRFS_FIRST_CHUNK_TREE_OBJECTID);
+ block_group->global_root_id);
btrfs_set_stack_block_group_flags(&bgi, block_group->flags);
key.objectid = block_group->start;
key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
@@ -34,6 +34,9 @@ static struct btrfs_root *btrfs_free_space_root(struct btrfs_fs_info *fs_info,
.offset = 0,
};
+ if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+ key.offset = block_group->global_root_id;
+
return btrfs_global_root(fs_info, &key);
}
We will now be using block_group->chunk_objectid to point at the global root id for this particular block group. For now we'll assign this based on mod'ing the offset of the block group against the number of global root id's and handle the block_group_item updating appropriately. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- kernel-shared/ctree.h | 2 ++ kernel-shared/disk-io.c | 24 ++++++++++++++++++++++-- kernel-shared/disk-io.h | 1 + kernel-shared/extent-tree.c | 17 +++++++++++++++-- kernel-shared/free-space-tree.c | 3 +++ 5 files changed, 43 insertions(+), 4 deletions(-)