btrfs: add block reserve for treelog
authorNaohiro Aota <naohiro.aota@wdc.com>
Wed, 23 Apr 2025 02:43:52 +0000 (11:43 +0900)
committerDavid Sterba <dsterba@suse.com>
Thu, 15 May 2025 12:30:53 +0000 (14:30 +0200)
We need to add a dedicated block_rsv for tree-log, because the block_rsv
serves for a tree node allocation in btrfs_alloc_tree_block(). Currently,
tree-log tree uses fs_info->empty_block_rsv, which is shared across trees
and points to the normal metadata space_info. Instead, we add a dedicated
block_rsv and that block_rsv can use the dedicated sub-space_info.

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-rsv.c
fs/btrfs/block-rsv.h
fs/btrfs/delalloc-space.c
fs/btrfs/disk-io.c
fs/btrfs/fs.h

index 3f36082..5ad6de7 100644 (file)
@@ -418,6 +418,9 @@ void btrfs_init_root_block_rsv(struct btrfs_root *root)
        case BTRFS_CHUNK_TREE_OBJECTID:
                root->block_rsv = &fs_info->chunk_block_rsv;
                break;
+       case BTRFS_TREE_LOG_OBJECTID:
+               root->block_rsv = &fs_info->treelog_rsv;
+               break;
        default:
                root->block_rsv = NULL;
                break;
@@ -438,6 +441,14 @@ void btrfs_init_global_block_rsv(struct btrfs_fs_info *fs_info)
        fs_info->delayed_block_rsv.space_info = space_info;
        fs_info->delayed_refs_rsv.space_info = space_info;
 
+       /* The treelog_rsv uses a dedicated space_info on the zoned mode. */
+       if (!btrfs_is_zoned(fs_info)) {
+               fs_info->treelog_rsv.space_info = space_info;
+       } else {
+               ASSERT(space_info->sub_group[0]->subgroup_id == BTRFS_SUB_GROUP_TREELOG);
+               fs_info->treelog_rsv.space_info = space_info->sub_group[0];
+       }
+
        btrfs_update_global_block_rsv(fs_info);
 }
 
index d12b1fa..79ae9d0 100644 (file)
@@ -24,6 +24,7 @@ enum btrfs_rsv_type {
        BTRFS_BLOCK_RSV_CHUNK,
        BTRFS_BLOCK_RSV_DELOPS,
        BTRFS_BLOCK_RSV_DELREFS,
+       BTRFS_BLOCK_RSV_TREELOG,
        BTRFS_BLOCK_RSV_EMPTY,
        BTRFS_BLOCK_RSV_TEMP,
 };
index 7128507..288e177 100644 (file)
@@ -115,8 +115,11 @@ static inline struct btrfs_space_info *data_sinfo_for_inode(const struct btrfs_i
 {
        struct btrfs_fs_info *fs_info = inode->root->fs_info;
 
-       if (btrfs_is_zoned(fs_info) && btrfs_is_data_reloc_root(inode->root))
-               return fs_info->data_sinfo->sub_group[SUB_GROUP_DATA_RELOC];
+       if (btrfs_is_zoned(fs_info) && btrfs_is_data_reloc_root(inode->root)) {
+               ASSERT(fs_info->data_sinfo->sub_group[0]->subgroup_id ==
+                      BTRFS_SUB_GROUP_DATA_RELOC);
+               return fs_info->data_sinfo->sub_group[0];
+       }
        return fs_info->data_sinfo;
 }
 
index 308e8f3..5bcf112 100644 (file)
@@ -2831,6 +2831,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
                             BTRFS_BLOCK_RSV_GLOBAL);
        btrfs_init_block_rsv(&fs_info->trans_block_rsv, BTRFS_BLOCK_RSV_TRANS);
        btrfs_init_block_rsv(&fs_info->chunk_block_rsv, BTRFS_BLOCK_RSV_CHUNK);
+       btrfs_init_block_rsv(&fs_info->treelog_rsv, BTRFS_BLOCK_RSV_TREELOG);
        btrfs_init_block_rsv(&fs_info->empty_block_rsv, BTRFS_BLOCK_RSV_EMPTY);
        btrfs_init_block_rsv(&fs_info->delayed_block_rsv,
                             BTRFS_BLOCK_RSV_DELOPS);
index 007b7c9..4394de1 100644 (file)
@@ -472,6 +472,8 @@ struct btrfs_fs_info {
        struct btrfs_block_rsv delayed_block_rsv;
        /* Block reservation for delayed refs */
        struct btrfs_block_rsv delayed_refs_rsv;
+       /* Block reservation for treelog tree */
+       struct btrfs_block_rsv treelog_rsv;
 
        struct btrfs_block_rsv empty_block_rsv;