btrfs: don't use size classes for zoned file systems
authorBoris Burkov <boris@bur.io>
Fri, 16 Dec 2022 00:06:35 +0000 (16:06 -0800)
committerDavid Sterba <dsterba@suse.com>
Mon, 13 Feb 2023 16:50:34 +0000 (17:50 +0100)
When a file system has ZNS devices which are constrained by a maximum
number of active block groups, then not being able to use all the block
groups for every allocation is not ideal, and could cause us to loop a
ton with mixed size allocations.

In general, since zoned doesn't write into gaps behind where block
groups are writing, it is not susceptible to the same sort of
fragmentation that size classes are designed to solve, so we can skip
size classes for zoned file systems in general, even though there would
probably be no harm for SMR devices.

Signed-off-by: Boris Burkov <boris@bur.io>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/block-group.c
fs/btrfs/block-group.h
fs/btrfs/extent-tree.c

index 8a711b42951597b30270689700675a625088b5f0..45ccb25c5b1fac1c19306e52fcc40ad2c794b208 100644 (file)
@@ -665,7 +665,7 @@ static int load_block_group_size_class(struct btrfs_caching_control *caching_ctl
        enum btrfs_block_group_size_class size_class = BTRFS_BG_SZ_NONE;
        int ret;
 
-       if (!btrfs_is_block_group_data_only(block_group))
+       if (!btrfs_block_group_should_use_size_class(block_group))
                return 0;
 
        for (i = 0; i < 5; ++i) {
@@ -3597,7 +3597,7 @@ int btrfs_add_reserved_bytes(struct btrfs_block_group *cache,
                goto out;
        }
 
-       if (btrfs_is_block_group_data_only(cache)) {
+       if (btrfs_block_group_should_use_size_class(cache)) {
                size_class = btrfs_calc_block_group_size_class(num_bytes);
                ret = btrfs_use_block_group_size_class(cache, size_class, force_wrong_size_class);
                if (ret)
@@ -4439,3 +4439,12 @@ int btrfs_use_block_group_size_class(struct btrfs_block_group *bg,
 
        return 0;
 }
+
+bool btrfs_block_group_should_use_size_class(struct btrfs_block_group *bg)
+{
+       if (btrfs_is_zoned(bg->fs_info))
+               return false;
+       if (!btrfs_is_block_group_data_only(bg))
+               return false;
+       return true;
+}
index 2b9d328b589ebad76d6a2e5d562aef673d4dafcd..4fdc39f00a4db52872377f3f2ab51180dc6870b6 100644 (file)
@@ -363,5 +363,6 @@ enum btrfs_block_group_size_class btrfs_calc_block_group_size_class(u64 size);
 int btrfs_use_block_group_size_class(struct btrfs_block_group *bg,
                                     enum btrfs_block_group_size_class size_class,
                                     bool force_wrong_size_class);
+bool btrfs_block_group_should_use_size_class(struct btrfs_block_group *bg);
 
 #endif /* BTRFS_BLOCK_GROUP_H */
index e9be9430faa089f20a4818357eb213fe23b50604..ad6c66ff9ba83ad6072a3564f245d3d071f0b4c0 100644 (file)
@@ -4064,7 +4064,7 @@ static bool find_free_extent_check_size_class(struct find_free_extent_ctl *ffe_c
 {
        if (ffe_ctl->policy == BTRFS_EXTENT_ALLOC_ZONED)
                return true;
-       if (!btrfs_is_block_group_data_only(bg))
+       if (!btrfs_block_group_should_use_size_class(bg))
                return true;
        if (ffe_ctl->loop >= LOOP_WRONG_SIZE_CLASS)
                return true;