@@ -80,6 +80,9 @@ struct btrfs_free_space_ctl;
/* hold the block group items. */
#define BTRFS_BLOCK_GROUP_TREE_OBJECTID 11ULL
+/* holds raid stripe entries */
+#define BTRFS_RAID_STRIPE_TREE_OBJECTID 12ULL
+
/* device stats in the device tree */
#define BTRFS_DEV_STATS_OBJECTID 0ULL
@@ -1214,6 +1217,7 @@ struct btrfs_fs_info {
struct btrfs_root *quota_root;
struct btrfs_root *uuid_root;
struct btrfs_root *block_group_root;
+ struct btrfs_root *stripe_root;
struct rb_root global_roots_tree;
struct rb_root fs_root_tree;
@@ -800,6 +800,12 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
return fs_info->block_group_root ? fs_info->block_group_root :
ERR_PTR(-ENOENT);
+#if EXPERIMENTAL
+ if (location->objectid == BTRFS_RAID_STRIPE_TREE_OBJECTID)
+ return fs_info->stripe_root ? fs_info->stripe_root :
+ ERR_PTR(-ENOENT);
+#endif
+
BUG_ON(location->objectid == BTRFS_TREE_RELOC_OBJECTID);
node = rb_search(&fs_info->fs_root_tree, (void *)&objectid,
@@ -832,6 +838,9 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
if (fs_info->quota_root)
free(fs_info->quota_root);
+ if (fs_info->stripe_root)
+ free(fs_info->stripe_root);
+
free_global_roots_tree(&fs_info->global_roots_tree);
free(fs_info->tree_root);
free(fs_info->chunk_root);
@@ -856,12 +865,14 @@ struct btrfs_fs_info *btrfs_new_fs_info(int writable, u64 sb_bytenr)
fs_info->dev_root = calloc(1, sizeof(struct btrfs_root));
fs_info->quota_root = calloc(1, sizeof(struct btrfs_root));
fs_info->uuid_root = calloc(1, sizeof(struct btrfs_root));
+ fs_info->stripe_root = calloc(1, sizeof(struct btrfs_root));
fs_info->block_group_root = calloc(1, sizeof(struct btrfs_root));
fs_info->super_copy = calloc(1, BTRFS_SUPER_INFO_SIZE);
if (!fs_info->tree_root || !fs_info->chunk_root || !fs_info->dev_root ||
!fs_info->quota_root || !fs_info->uuid_root ||
- !fs_info->block_group_root || !fs_info->super_copy)
+ !fs_info->block_group_root || !fs_info->super_copy ||
+ !fs_info->stripe_root)
goto free_all;
extent_buffer_init_cache(fs_info);
@@ -1270,6 +1281,23 @@ int btrfs_setup_all_roots(struct btrfs_fs_info *fs_info, u64 root_tree_bytenr,
return -EIO;
}
+#if EXPERIMENTAL
+ if (btrfs_fs_incompat(fs_info, RAID_STRIPE_TREE)) {
+ ret = btrfs_find_and_setup_root(root, fs_info,
+ BTRFS_RAID_STRIPE_TREE_OBJECTID,
+ fs_info->stripe_root);
+ if (ret) {
+ free(fs_info->stripe_root);
+ fs_info->stripe_root = NULL;
+ } else {
+ fs_info->stripe_root->track_dirty = 1;
+ }
+ } else {
+ free(fs_info->stripe_root);
+ fs_info->stripe_root = NULL;
+ }
+#endif
+
if (maybe_load_block_groups(fs_info, flags)) {
ret = btrfs_read_block_groups(fs_info);
/*
@@ -1327,6 +1355,8 @@ void btrfs_release_all_roots(struct btrfs_fs_info *fs_info)
free_extent_buffer(fs_info->chunk_root->node);
if (fs_info->uuid_root)
free_extent_buffer(fs_info->uuid_root->node);
+ if (fs_info->stripe_root)
+ free_extent_buffer(fs_info->stripe_root->node);
}
static void free_map_lookup(struct cache_extent *ce)
When encountering a filesystem formatted with the raid stripe tree feature, read it from disk. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> --- kernel-shared/ctree.h | 4 ++++ kernel-shared/disk-io.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-)