@@ -1262,6 +1262,8 @@ struct btrfs_fs_info {
u32 sectorsize;
u32 stripesize;
+ u64 num_global_roots;
+
/*
* Zone size > 0 when in ZONED mode, otherwise it's used for a check
* if the mode is enabled
@@ -1450,6 +1450,44 @@ int btrfs_setup_chunk_tree_and_device_map(struct btrfs_fs_info *fs_info,
return 0;
}
+static int btrfs_get_global_roots_count(struct btrfs_fs_info *fs_info)
+{
+ struct btrfs_key key = {
+ .objectid = BTRFS_EXTENT_TREE_OBJECTID,
+ .type = BTRFS_ROOT_ITEM_KEY,
+ .offset = (u64)-1,
+ };
+ struct btrfs_path *path;
+ int ret;
+
+ if (!btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+ return 0;
+
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+ ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0);
+ if (ret < 0)
+ goto out;
+ if (ret == 0) {
+ ret = -EINVAL;
+ error("Found a corrupt root item looking for global roots count");
+ goto out;
+ }
+ ret = btrfs_previous_item(fs_info->tree_root, path, key.objectid,
+ key.type);
+ if (ret) {
+ ret = -EINVAL;
+ error("Didn't find a extent root looking for global roots count");
+ goto out;
+ }
+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+ fs_info->num_global_roots = key.offset + 1;
+out:
+ btrfs_free_path(path);
+ return ret;
+}
+
static struct btrfs_fs_info *__open_ctree_fd(int fp, struct open_ctree_flags *ocf)
{
struct btrfs_fs_info *fs_info;
@@ -1596,6 +1634,10 @@ static struct btrfs_fs_info *__open_ctree_fd(int fp, struct open_ctree_flags *oc
!fs_info->ignore_chunk_tree_error)
goto out_chunk;
+ ret = btrfs_get_global_roots_count(fs_info);
+ if (ret && !(flags & OPEN_CTREE_PARTIAL))
+ goto out_chunk;
+
return fs_info;
out_chunk:
We need to know how many global roots we have in order to round robin assign block groups to their specific global root. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- kernel-shared/ctree.h | 2 ++ kernel-shared/disk-io.c | 42 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+)