Re: [RFC ONLY 3/8] btrfs: read raid-stripe-tree from disk

Qu Wenruo
2022-05-17T08:10:17Z

On 2022/5/16 22:31, Johannes Thumshirn wrote:
> If we're discovering a raid-stripe-tree on mount, read it from disk.
>
> Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
> ---
> fs/btrfs/ctree.h | 1 +
> fs/btrfs/disk-io.c | 12 ++++++++++++
> include/uapi/linux/btrfs.h | 1 +
> 3 files changed, 14 insertions(+)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 20aa2ebac7cd..1db669662f61 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -667,6 +667,7 @@ struct btrfs_fs_info {
> struct btrfs_root *uuid_root;
> struct btrfs_root *data_reloc_root;
> struct btrfs_root *block_group_root;
> + struct btrfs_root *stripe_root;
>
> /* the log root tree is a directory of all the other log roots */
> struct btrfs_root *log_root_tree;
> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
> index d456f426924c..c0f08917465a 100644
> --- a/fs/btrfs/disk-io.c
> +++ b/fs/btrfs/disk-io.c
> @@ -1706,6 +1706,9 @@ static struct btrfs_root *btrfs_get_global_root(struct btrfs_fs_info *fs_info,
>
> return btrfs_grab_root(root) ? root : ERR_PTR(-ENOENT);
> }
> + if (objectid == BTRFS_RAID_STRIPE_TREE_OBJECTID)
> + return btrfs_grab_root(fs_info->stripe_root) ?
> + fs_info->stripe_root : ERR_PTR(-ENOENT);
> return NULL;
> }
>
> @@ -1784,6 +1787,7 @@ void btrfs_free_fs_info(struct btrfs_fs_info *fs_info)
> btrfs_put_root(fs_info->fs_root);
> btrfs_put_root(fs_info->data_reloc_root);
> btrfs_put_root(fs_info->block_group_root);
> + btrfs_put_root(fs_info->stripe_root);
> btrfs_check_leaked_roots(fs_info);
> btrfs_extent_buffer_leak_debug_check(fs_info);
> kfree(fs_info->super_copy);
> @@ -2337,6 +2341,7 @@ static void free_root_pointers(struct btrfs_fs_info *info, bool free_chunk_root)
> free_root_extent_buffers(info->fs_root);
> free_root_extent_buffers(info->data_reloc_root);
> free_root_extent_buffers(info->block_group_root);
> + free_root_extent_buffers(info->stripe_root);
> if (free_chunk_root)
> free_root_extent_buffers(info->chunk_root);
> }
> @@ -2773,6 +2778,13 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
> fs_info->uuid_root = root;
> }
>

I guess in the real patch, we need to check the incompatble feature first.

Another problem is, how do we do bootstrap?

If our metadata (especially chunk tree) is also in some chunks which is
stripe-tree mapped, without stripe tree we're even unable to read the
chunk tree.

Or do you plan to not support metadata on stripe-tree mapped chunks?

Thanks,
Qu
> + location.objectid = BTRFS_RAID_STRIPE_TREE_OBJECTID;
> + root = btrfs_read_tree_root(tree_root, &location);
> + if (!IS_ERR(root)) {
> + set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
> + fs_info->stripe_root = root;
> + }
> +
> return 0;
> out:
> btrfs_warn(fs_info, "failed to read root (objectid=%llu): %d",
> diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
> index d956b2993970..4e0429fc4e87 100644
> --- a/include/uapi/linux/btrfs.h
> +++ b/include/uapi/linux/btrfs.h
> @@ -310,6 +310,7 @@ struct btrfs_ioctl_fs_info_args {
> #define BTRFS_FEATURE_INCOMPAT_RAID1C34 (1ULL << 11)
> #define BTRFS_FEATURE_INCOMPAT_ZONED (1ULL << 12)
> #define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 (1ULL << 13)
> +#define BTRFS_FEATURE_INCOMPAT_STRIPE_TREE (1ULL << 14)
>
> struct btrfs_ioctl_feature_flags {
> __u64 compat_flags;