]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
btrfs: remove op field from struct btrfs_free_space_ctl
authorFilipe Manana <fdmanana@suse.com>
Wed, 15 Apr 2026 18:34:38 +0000 (19:34 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 8 Jun 2026 13:53:29 +0000 (15:53 +0200)
The op field always points to the same use_bitmap function, the only
exception is during self tests where we make it temporarily point to a
different function. So just because of this op pointer field we are
increasing the structure size by 8 bytes.

Instead of storing a pointer to a use_bitmap function in struct
btrfs_free_space_ctl, move the pointer to struct btrfs_info, make
insert_into_bitmap() use that pointer if we are running the self tests
and initialize that pointer to the current, default use_bitmap function
(now exported for the tests as btrfs_use_bitmap). This way we reduce
the size of struct btrfs_free_space_ctl from 136 to 128 bytes and can
now fit 32 structures in a 4K page instead of 30. This also avoids the
cost of the indirection of a function pointer call when we are not
running the self tests.

Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/free-space-cache.c
fs/btrfs/free-space-cache.h
fs/btrfs/fs.h
fs/btrfs/tests/btrfs-tests.c
fs/btrfs/tests/free-space-tests.c

index c71249ee3214e4d8a4b1e06d17b1716d71888a1e..f0c808a89eafac610355afe0e535dfacb62481c2 100644 (file)
@@ -2253,7 +2253,8 @@ static u64 add_bytes_to_bitmap(struct btrfs_free_space_ctl *ctl,
 
 }
 
-static bool use_bitmap(struct btrfs_free_space_ctl *ctl,
+EXPORT_FOR_TESTS
+bool btrfs_use_bitmap(struct btrfs_free_space_ctl *ctl,
                      struct btrfs_free_space *info)
 {
        struct btrfs_block_group *block_group = ctl->block_group;
@@ -2303,15 +2304,11 @@ static bool use_bitmap(struct btrfs_free_space_ctl *ctl,
        return true;
 }
 
-static const struct btrfs_free_space_op free_space_op = {
-       .use_bitmap             = use_bitmap,
-};
-
 static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
                              struct btrfs_free_space *info)
 {
        struct btrfs_free_space *bitmap_info;
-       struct btrfs_block_group *block_group = NULL;
+       struct btrfs_block_group *block_group = ctl->block_group;
        int added = 0;
        u64 bytes, offset, bytes_added;
        enum btrfs_trim_state trim_state;
@@ -2321,18 +2318,20 @@ static int insert_into_bitmap(struct btrfs_free_space_ctl *ctl,
        offset = info->offset;
        trim_state = info->trim_state;
 
-       if (!ctl->op->use_bitmap(ctl, info))
-               return 0;
-
-       if (ctl->op == &free_space_op)
-               block_group = ctl->block_group;
+       if (btrfs_is_testing(block_group->fs_info)) {
+               if (!block_group->fs_info->use_bitmap(ctl, info))
+                       return 0;
+       } else {
+               if (!btrfs_use_bitmap(ctl, info))
+                       return 0;
+       }
 again:
        /*
         * Since we link bitmaps right into the cluster we need to see if we
         * have a cluster here, and if so and it has our bitmap we need to add
         * the free space to that bitmap.
         */
-       if (block_group && !list_empty(&block_group->cluster_list)) {
+       if (!list_empty(&block_group->cluster_list)) {
                struct btrfs_free_cluster *cluster;
                struct rb_node *node;
                struct btrfs_free_space *entry;
@@ -2953,7 +2952,6 @@ void btrfs_init_free_space_ctl(struct btrfs_block_group *block_group,
 {
        spin_lock_init(&ctl->tree_lock);
        ctl->block_group = block_group;
-       ctl->op = &free_space_op;
        ctl->free_space_bytes = RB_ROOT_CACHED;
        INIT_LIST_HEAD(&ctl->trimming_ranges);
        mutex_init(&ctl->cache_writeout_mutex);
index c5d0f3e056cc0a0b7ac6c6b8b4bb93e1bd6b3518..53fe8e293af1d5c1c61b4af452bd089f57e9d9aa 100644 (file)
@@ -83,17 +83,11 @@ struct btrfs_free_space_ctl {
        u64 free_space;
        s32 discardable_extents[BTRFS_STAT_NR_ENTRIES];
        s64 discardable_bytes[BTRFS_STAT_NR_ENTRIES];
-       const struct btrfs_free_space_op *op;
        struct btrfs_block_group *block_group;
        struct mutex cache_writeout_mutex;
        struct list_head trimming_ranges;
 };
 
-struct btrfs_free_space_op {
-       bool (*use_bitmap)(struct btrfs_free_space_ctl *ctl,
-                          struct btrfs_free_space *info);
-};
-
 struct btrfs_io_ctl {
        void *cur, *orig;
        struct page *page;
@@ -170,6 +164,8 @@ bool btrfs_free_space_cache_v1_active(struct btrfs_fs_info *fs_info);
 int btrfs_set_free_space_cache_v1_active(struct btrfs_fs_info *fs_info, bool active);
 /* Support functions for running our sanity tests */
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
+bool btrfs_use_bitmap(struct btrfs_free_space_ctl *ctl,
+                     struct btrfs_free_space *info);
 int test_add_free_space_entry(struct btrfs_block_group *cache,
                              u64 offset, u64 bytes, bool bitmap);
 int test_check_exists(struct btrfs_block_group *cache, u64 offset, u64 bytes);
index 8fead5e8d2d01ea35a7bda16b5a39f4dcd93753c..248014d3a1ee025dcd86c1ac2a9d97c4defccdb7 100644 (file)
@@ -486,6 +486,9 @@ struct btrfs_delayed_root {
        wait_queue_head_t wait;
 };
 
+struct btrfs_free_space_ctl;
+struct btrfs_free_space;
+
 struct btrfs_fs_info {
        u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
        unsigned long flags;
@@ -951,6 +954,10 @@ struct btrfs_fs_info {
        spinlock_t eb_leak_lock;
        struct list_head allocated_ebs;
 #endif
+
+       /* Used by self tests only. */
+       bool (*use_bitmap)(struct btrfs_free_space_ctl *ctl,
+                          struct btrfs_free_space *info);
 };
 
 #define folio_to_inode(_folio) (BTRFS_I(_Generic((_folio),                     \
index 19c127ac6d10cb4b625cb8089d3f2961a640514a..6287d940323d693de8ef7d99b912c2728e4cec46 100644 (file)
@@ -145,6 +145,7 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
        fs_info->csum_size = 4;
        fs_info->csums_per_leaf = BTRFS_MAX_ITEM_SIZE(fs_info) /
                fs_info->csum_size;
+       fs_info->use_bitmap = btrfs_use_bitmap;
        set_bit(BTRFS_FS_STATE_DUMMY_FS_INFO, &fs_info->fs_state);
 
        test_mnt->mnt_sb->s_fs_info = fs_info;
index ebf68fcd2149de122f25013d44c45705257bd023..0425b3b68716aa23a85c2d1bf2df6eb2b79371a6 100644 (file)
@@ -398,10 +398,8 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group *cache,
        int ret;
        u64 offset;
        u64 max_extent_size;
-       const struct btrfs_free_space_op test_free_space_ops = {
-               .use_bitmap = test_use_bitmap,
-       };
-       const struct btrfs_free_space_op *orig_free_space_ops;
+       bool (*orig_use_bitmap)(struct btrfs_free_space_ctl *ctl,
+                               struct btrfs_free_space *info);
 
        test_msg("running space stealing from bitmap to extent tests");
 
@@ -423,8 +421,8 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group *cache,
         * that forces use of bitmaps as soon as we have at least 1
         * extent entry.
         */
-       orig_free_space_ops = cache->free_space_ctl->op;
-       cache->free_space_ctl->op = &test_free_space_ops;
+       orig_use_bitmap = cache->fs_info->use_bitmap;
+       cache->fs_info->use_bitmap = test_use_bitmap;
 
        /*
         * Extent entry covering free space range [128Mb - 256Kb, 128Mb - 128Kb[
@@ -818,7 +816,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group *cache,
        if (ret)
                return ret;
 
-       cache->free_space_ctl->op = orig_free_space_ops;
+       cache->fs_info->use_bitmap = orig_use_bitmap;
        btrfs_remove_free_space_cache(cache);
 
        return 0;
@@ -832,10 +830,8 @@ static bool bytes_index_use_bitmap(struct btrfs_free_space_ctl *ctl,
 
 static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize)
 {
-       const struct btrfs_free_space_op test_free_space_ops = {
-               .use_bitmap = bytes_index_use_bitmap,
-       };
-       const struct btrfs_free_space_op *orig_free_space_ops;
+       bool (*orig_use_bitmap)(struct btrfs_free_space_ctl *ctl,
+                               struct btrfs_free_space *info);
        struct btrfs_free_space_ctl *ctl = cache->free_space_ctl;
        struct btrfs_free_space *entry;
        struct rb_node *node;
@@ -892,8 +888,8 @@ static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize)
 
        /* Now validate bitmaps with different ->max_extent_size. */
        btrfs_remove_free_space_cache(cache);
-       orig_free_space_ops = cache->free_space_ctl->op;
-       cache->free_space_ctl->op = &test_free_space_ops;
+       orig_use_bitmap = cache->fs_info->use_bitmap;
+       cache->fs_info->use_bitmap = bytes_index_use_bitmap;
 
        ret = test_add_free_space_entry(cache, 0, sectorsize, 1);
        if (ret) {
@@ -997,7 +993,7 @@ static int test_bytes_index(struct btrfs_block_group *cache, u32 sectorsize)
                return -EINVAL;
        }
 
-       cache->free_space_ctl->op = orig_free_space_ops;
+       cache->fs_info->use_bitmap = orig_use_bitmap;
        btrfs_remove_free_space_cache(cache);
        return 0;
 }