]> git.dujemihanovic.xyz Git - linux.git/commitdiff
btrfs: separate BLOCK_GROUP_TREE compat RO flag from EXTENT_TREE_V2
authorQu Wenruo <wqu@suse.com>
Tue, 9 Aug 2022 05:02:18 +0000 (13:02 +0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 26 Sep 2022 10:28:00 +0000 (12:28 +0200)
The problem of long mount time caused by block group item search is
already known for some time, and the solution of block group tree has
been proposed.

There is really no need to bound this feature into extent tree v2, just
introduce compat RO flag, BLOCK_GROUP_TREE, to correctly solve the
problem.

All the code handling block group root is already in the upstream
kernel, thus this patch really only needs to introduce the new compat RO
flag.

This patch introduces one extra artificial limitation on block group
tree feature, that free space cache v2 and no-holes feature must be
enabled to use this new compat RO feature.

This artificial requirement is mostly to reduce the test combinations,
and can be a guideline for future features, to mostly rely on the latest
default features.

Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/disk-io.h
fs/btrfs/sysfs.c
include/uapi/linux/btrfs.h

index 2c38daa822efdd71a2a4336a985bbf7f74115764..7007c7974a2ee9fbf6c3f37aeb84de0704f3869f 100644 (file)
@@ -302,7 +302,8 @@ static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
 #define BTRFS_FEATURE_COMPAT_RO_SUPP                   \
        (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE |      \
         BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID | \
-        BTRFS_FEATURE_COMPAT_RO_VERITY)
+        BTRFS_FEATURE_COMPAT_RO_VERITY |               \
+        BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE)
 
 #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET       0ULL
 #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR     0ULL
index dfc9b3aea76a7c9528c5f801e6e029fa2e87f762..120b7697ab4287f0c21cbdb9dbca54e8a1a25321 100644 (file)
@@ -1981,7 +1981,7 @@ static void backup_super_roots(struct btrfs_fs_info *info)
        btrfs_set_backup_chunk_root_level(root_backup,
                               btrfs_header_level(info->chunk_root->node));
 
-       if (!btrfs_fs_incompat(info, EXTENT_TREE_V2)) {
+       if (!btrfs_fs_compat_ro(info, BLOCK_GROUP_TREE)) {
                struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
                struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
 
@@ -2526,7 +2526,7 @@ static int btrfs_read_roots(struct btrfs_fs_info *fs_info)
        location.type = BTRFS_ROOT_ITEM_KEY;
        location.offset = 0;
 
-       if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
+       if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE)) {
                location.objectid = BTRFS_BLOCK_GROUP_TREE_OBJECTID;
                root = btrfs_read_tree_root(tree_root, &location);
                if (IS_ERR(root)) {
@@ -2711,6 +2711,18 @@ int btrfs_validate_super(struct btrfs_fs_info *fs_info,
                ret = -EINVAL;
        }
 
+       /*
+        * Artificial requirement for block-group-tree to force newer features
+        * (free-space-tree, no-holes) so the test matrix is smaller.
+        */
+       if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE) &&
+           (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID) ||
+            !btrfs_fs_incompat(fs_info, NO_HOLES))) {
+               btrfs_err(fs_info,
+               "block-group-tree feature requires fres-space-tree and no-holes");
+               ret = -EINVAL;
+       }
+
        if (memcmp(fs_info->fs_devices->metadata_uuid, sb->dev_item.fsid,
                   BTRFS_FSID_SIZE) != 0) {
                btrfs_err(fs_info,
@@ -2880,16 +2892,6 @@ static int __cold init_tree_roots(struct btrfs_fs_info *fs_info)
        int ret = 0;
        int i;
 
-       if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2)) {
-               struct btrfs_root *root;
-
-               root = btrfs_alloc_root(fs_info, BTRFS_BLOCK_GROUP_TREE_OBJECTID,
-                                       GFP_KERNEL);
-               if (!root)
-                       return -ENOMEM;
-               fs_info->block_group_root = root;
-       }
-
        for (i = 0; i < BTRFS_NUM_BACKUP_ROOTS; i++) {
                if (handle_error) {
                        if (!IS_ERR(tree_root->node))
index aef981de672c4094b42335a80e574f21e7a44ffe..7e545ec09a10b759ad5f446a747de9594dacf069 100644 (file)
@@ -105,7 +105,7 @@ static inline struct btrfs_root *btrfs_grab_root(struct btrfs_root *root)
 
 static inline struct btrfs_root *btrfs_block_group_root(struct btrfs_fs_info *fs_info)
 {
-       if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
+       if (btrfs_fs_compat_ro(fs_info, BLOCK_GROUP_TREE))
                return fs_info->block_group_root;
        return btrfs_extent_root(fs_info, 0);
 }
index 84a992681801bc0d5eaa3b315386048976957633..6816bc41c22886e9083ecec0af08cf610afbb73e 100644 (file)
@@ -286,6 +286,7 @@ BTRFS_FEAT_ATTR_INCOMPAT(skinny_metadata, SKINNY_METADATA);
 BTRFS_FEAT_ATTR_INCOMPAT(no_holes, NO_HOLES);
 BTRFS_FEAT_ATTR_INCOMPAT(metadata_uuid, METADATA_UUID);
 BTRFS_FEAT_ATTR_COMPAT_RO(free_space_tree, FREE_SPACE_TREE);
+BTRFS_FEAT_ATTR_COMPAT_RO(block_group_tree, BLOCK_GROUP_TREE);
 BTRFS_FEAT_ATTR_INCOMPAT(raid1c34, RAID1C34);
 #ifdef CONFIG_BLK_DEV_ZONED
 BTRFS_FEAT_ATTR_INCOMPAT(zoned, ZONED);
@@ -317,6 +318,7 @@ static struct attribute *btrfs_supported_feature_attrs[] = {
        BTRFS_FEAT_ATTR_PTR(metadata_uuid),
        BTRFS_FEAT_ATTR_PTR(free_space_tree),
        BTRFS_FEAT_ATTR_PTR(raid1c34),
+       BTRFS_FEAT_ATTR_PTR(block_group_tree),
 #ifdef CONFIG_BLK_DEV_ZONED
        BTRFS_FEAT_ATTR_PTR(zoned),
 #endif
index 7ada84e4a3ed11055d0f4497199267a687979abe..5655e89b962be87e5bd6cb1710669cbffad676a0 100644 (file)
@@ -290,6 +290,12 @@ struct btrfs_ioctl_fs_info_args {
 #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID  (1ULL << 1)
 #define BTRFS_FEATURE_COMPAT_RO_VERITY                 (1ULL << 2)
 
+/*
+ * Put all block group items into a dedicated block group tree, greatly
+ * reducing mount time for large filesystem due to better locality.
+ */
+#define BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE       (1ULL << 3)
+
 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF   (1ULL << 0)
 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL  (1ULL << 1)
 #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS    (1ULL << 2)