]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dm vdo: update vdo_allocate_extended to take a field name, no types
authorKen Raeburn <raeburn@redhat.com>
Fri, 27 Feb 2026 01:12:06 +0000 (20:12 -0500)
committerMikulas Patocka <mpatocka@redhat.com>
Mon, 2 Mar 2026 16:03:18 +0000 (17:03 +0100)
All of VDO's "extended" allocations use a flexible array field at the
end of the allocated structure. We can infer the struct type from the
supplied pointer. Replacing the array field type with the field name
lets us use struct_size from overflow.h to compute the size instead of
the local __vdo_do_allocation version.

One allocation of bio structures doesn't conform to this pattern,
since the removal of bi_inline_vecs; directly compute the total size
for that case.

Signed-off-by: Ken Raeburn <raeburn@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
17 files changed:
drivers/md/dm-vdo/block-map.c
drivers/md/dm-vdo/data-vio.c
drivers/md/dm-vdo/dedupe.c
drivers/md/dm-vdo/indexer/index-layout.c
drivers/md/dm-vdo/indexer/index.c
drivers/md/dm-vdo/indexer/open-chapter.c
drivers/md/dm-vdo/indexer/radix-sort.c
drivers/md/dm-vdo/io-submitter.c
drivers/md/dm-vdo/logical-zone.c
drivers/md/dm-vdo/memory-alloc.h
drivers/md/dm-vdo/packer.c
drivers/md/dm-vdo/physical-zone.c
drivers/md/dm-vdo/priority-table.c
drivers/md/dm-vdo/recovery-journal.c
drivers/md/dm-vdo/repair.c
drivers/md/dm-vdo/slab-depot.c
drivers/md/dm-vdo/vio.c

index a7db5b41155e9a22a8b001e87c1d65f25562cd8d..25eda82a96359b15f5fe0b6c671e8273e595d973 100644 (file)
@@ -2478,9 +2478,7 @@ static int make_forest(struct block_map *map, block_count_t entries)
                return VDO_SUCCESS;
        }
 
-       result = vdo_allocate_extended(struct forest, map->root_count,
-                                      struct block_map_tree, __func__,
-                                      &forest);
+       result = vdo_allocate_extended(map->root_count, trees, __func__, &forest);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -2707,8 +2705,7 @@ void vdo_traverse_forest(struct block_map *map, vdo_entry_callback_fn callback,
        struct cursors *cursors;
        int result;
 
-       result = vdo_allocate_extended(struct cursors, map->root_count,
-                                      struct cursor, __func__, &cursors);
+       result = vdo_allocate_extended(map->root_count, cursors, __func__, &cursors);
        if (result != VDO_SUCCESS) {
                vdo_fail_completion(completion, result);
                return;
@@ -2758,9 +2755,7 @@ static int __must_check initialize_block_map_zone(struct block_map *map,
        zone->thread_id = vdo->thread_config.logical_threads[zone_number];
        zone->block_map = map;
 
-       result = vdo_allocate_extended(struct dirty_lists, maximum_age,
-                                      dirty_era_t, __func__,
-                                      &zone->dirty_lists);
+       result = vdo_allocate_extended(maximum_age, eras, __func__, &zone->dirty_lists);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -2900,9 +2895,8 @@ int vdo_decode_block_map(struct block_map_state_2_0 state, block_count_t logical
        if (result != VDO_SUCCESS)
                return result;
 
-       result = vdo_allocate_extended(struct block_map,
-                                      vdo->thread_config.logical_zone_count,
-                                      struct block_map_zone, __func__, &map);
+       result = vdo_allocate_extended(vdo->thread_config.logical_zone_count,
+                                      zones, __func__, &map);
        if (result != VDO_SUCCESS)
                return result;
 
index 3333e1e5b02ee796d4a31a39a72ff121d6941380..370d4239ba31548ae776509d0ddaa5335253e8f3 100644 (file)
@@ -842,8 +842,7 @@ int make_data_vio_pool(struct vdo *vdo, data_vio_count_t pool_size,
        struct data_vio_pool *pool;
        data_vio_count_t i;
 
-       result = vdo_allocate_extended(struct data_vio_pool, pool_size, struct data_vio,
-                                      __func__, &pool);
+       result = vdo_allocate_extended(pool_size, data_vios, __func__, &pool);
        if (result != VDO_SUCCESS)
                return result;
 
index 75a26f3f44610029a460ff0a9f75fdf0d35cf865..36e9f123602539f5e84083637fa0f80b0cfe88cb 100644 (file)
@@ -2418,8 +2418,7 @@ int vdo_make_hash_zones(struct vdo *vdo, struct hash_zones **zones_ptr)
        if (zone_count == 0)
                return VDO_SUCCESS;
 
-       result = vdo_allocate_extended(struct hash_zones, zone_count, struct hash_zone,
-                                      __func__, &zones);
+       result = vdo_allocate_extended(zone_count, zones, __func__, &zones);
        if (result != VDO_SUCCESS)
                return result;
 
index 37144249f7ba6b860e2d2fa721c550aab533071e..76bcc0ae76cc918438664250bfdb00428c5b71bb 100644 (file)
@@ -459,8 +459,7 @@ static int __must_check make_index_save_region_table(struct index_save_layout *i
                type = RH_TYPE_UNSAVED;
        }
 
-       result = vdo_allocate_extended(struct region_table, region_count,
-                                      struct layout_region,
+       result = vdo_allocate_extended(region_count, regions,
                                       "layout region table for ISL", &table);
        if (result != VDO_SUCCESS)
                return result;
@@ -642,9 +641,8 @@ static int __must_check make_layout_region_table(struct index_layout *layout,
        struct region_table *table;
        struct layout_region *lr;
 
-       result = vdo_allocate_extended(struct region_table, region_count,
-                                      struct layout_region, "layout region table",
-                                      &table);
+       result = vdo_allocate_extended(region_count, regions,
+                                      "layout region table", &table);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -1138,8 +1136,7 @@ static int __must_check load_region_table(struct buffered_reader *reader,
                                              header.version);
        }
 
-       result = vdo_allocate_extended(struct region_table, header.region_count,
-                                      struct layout_region,
+       result = vdo_allocate_extended(header.region_count, regions,
                                       "single file layout region table", &table);
        if (result != VDO_SUCCESS)
                return result;
index df49348462441a0f6d7e3f6b5fabb885df9be32f..d4724fe17bf1af02bf146456fa87f3370dc85710 100644 (file)
@@ -764,9 +764,7 @@ static int make_chapter_writer(struct uds_index *index,
        size_t collated_records_size =
                (sizeof(struct uds_volume_record) * index->volume->geometry->records_per_chapter);
 
-       result = vdo_allocate_extended(struct chapter_writer, index->zone_count,
-                                      struct open_chapter_zone *, "Chapter Writer",
-                                      &writer);
+       result = vdo_allocate_extended(index->zone_count, chapters, "Chapter Writer", &writer);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -1160,8 +1158,7 @@ int uds_make_index(struct uds_configuration *config, enum uds_open_index_type op
        u64 nonce;
        unsigned int z;
 
-       result = vdo_allocate_extended(struct uds_index, config->zone_count,
-                                      struct uds_request_queue *, "index", &index);
+       result = vdo_allocate_extended(config->zone_count, zone_queues, "index", &index);
        if (result != VDO_SUCCESS)
                return result;
 
index 4a67bcadaae0a1d23431f7492b1b40881471ef39..89b91c600bfd6071505cfcb1e0b7509bf4e8ba7e 100644 (file)
@@ -68,9 +68,7 @@ int uds_make_open_chapter(const struct index_geometry *geometry, unsigned int zo
        size_t capacity = geometry->records_per_chapter / zone_count;
        size_t slot_count = (1 << bits_per(capacity * LOAD_RATIO));
 
-       result = vdo_allocate_extended(struct open_chapter_zone, slot_count,
-                                      struct open_chapter_zone_slot, "open chapter",
-                                      &open_chapter);
+       result = vdo_allocate_extended(slot_count, slots, "open chapter", &open_chapter);
        if (result != VDO_SUCCESS)
                return result;
 
index 66b8c706a1ef9a19c5aea930af5914bdfa29b1a5..4b81e130d18a504d13c5ba58b9f455f2cf246d5b 100644 (file)
@@ -211,8 +211,7 @@ int uds_make_radix_sorter(unsigned int count, struct radix_sorter **sorter)
        unsigned int stack_size = count / INSERTION_SORT_THRESHOLD;
        struct radix_sorter *radix_sorter;
 
-       result = vdo_allocate_extended(struct radix_sorter, stack_size, struct task,
-                                      __func__, &radix_sorter);
+       result = vdo_allocate_extended(stack_size, stack, __func__, &radix_sorter);
        if (result != VDO_SUCCESS)
                return result;
 
index e26d75f8366ddecfc50207f65fad6721505ab413..0e9932929fee70b5ad0814d4da53195489022a0e 100644 (file)
@@ -383,8 +383,7 @@ int vdo_make_io_submitter(unsigned int thread_count, unsigned int rotation_inter
        struct io_submitter *io_submitter;
        int result;
 
-       result = vdo_allocate_extended(struct io_submitter, thread_count,
-                                      struct bio_queue_data, "bio submission data",
+       result = vdo_allocate_extended(thread_count, bio_queue_data, "bio submission data",
                                       &io_submitter);
        if (result != VDO_SUCCESS)
                return result;
index 0a27e60a9dfd70c83a48e969c9fc23898cc6b84d..fa7c3eb7ee6bf825936f99b42cb53191df203069 100644 (file)
@@ -94,8 +94,7 @@ int vdo_make_logical_zones(struct vdo *vdo, struct logical_zones **zones_ptr)
        if (zone_count == 0)
                return VDO_SUCCESS;
 
-       result = vdo_allocate_extended(struct logical_zones, zone_count,
-                                      struct logical_zone, __func__, &zones);
+       result = vdo_allocate_extended(zone_count, zones, __func__, &zones);
        if (result != VDO_SUCCESS)
                return result;
 
index 0093d9f940d98b0e0576548b79e29bb27e0e1692..ab2375d549f4aaf92ea236f2b98a13ff1fd14fb6 100644 (file)
@@ -8,6 +8,7 @@
 
 #include <linux/cache.h>
 #include <linux/io.h> /* for PAGE_SIZE */
+#include <linux/overflow.h>
 
 #include "permassert.h"
 #include "thread-registry.h"
@@ -71,31 +72,21 @@ static inline int __vdo_do_allocation(size_t count, size_t size, size_t extra,
        __vdo_do_allocation(COUNT, sizeof(TYPE), 0, __alignof__(TYPE), WHAT, PTR)
 
 /*
- * Allocate one object of an indicated type, followed by one or more elements of a second type,
- * logging an error if the allocation fails. The memory will be zeroed.
+ * Allocate a structure with a flexible array member, with a specified number of elements, logging
+ * an error if the allocation fails. The memory will be zeroed.
  *
- * @TYPE1: The type of the primary object to allocate. This type determines the alignment of the
- *         allocated memory.
  * @COUNT: The number of objects to allocate
- * @TYPE2: The type of array objects to allocate
+ * @FIELD: The flexible array field at the end of the structure
  * @WHAT: What is being allocated (for error logging)
  * @PTR: A pointer to hold the allocated memory
  *
  * Return: VDO_SUCCESS or an error code
  */
-#define vdo_allocate_extended(TYPE1, COUNT, TYPE2, WHAT, PTR)          \
-       __extension__({                                                 \
-               int _result;                                            \
-               TYPE1 **_ptr = (PTR);                                   \
-               BUILD_BUG_ON(__alignof__(TYPE1) < __alignof__(TYPE2));  \
-               _result = __vdo_do_allocation(COUNT,                    \
-                                             sizeof(TYPE2),            \
-                                             sizeof(TYPE1),            \
-                                             __alignof__(TYPE1),       \
-                                             WHAT,                     \
-                                             _ptr);                    \
-               _result;                                                \
-       })
+#define vdo_allocate_extended(COUNT, FIELD, WHAT, PTR)                 \
+       vdo_allocate_memory(struct_size(*(PTR), FIELD, (COUNT)),        \
+                           __alignof__(typeof(**(PTR))),               \
+                           WHAT,                                       \
+                           (PTR))
 
 /*
  * Allocate memory starting on a cache line boundary, logging an error if the allocation fails. The
index 666be6d557e1001c0eac46092d8b5705a6154e0c..e638694d896cec1b8d8717b8ecf6155f0ff4bef3 100644 (file)
@@ -120,8 +120,7 @@ static int __must_check make_bin(struct packer *packer)
        struct packer_bin *bin;
        int result;
 
-       result = vdo_allocate_extended(struct packer_bin, VDO_MAX_COMPRESSION_SLOTS,
-                                      struct vio *, __func__, &bin);
+       result = vdo_allocate_extended(VDO_MAX_COMPRESSION_SLOTS, incoming, __func__, &bin);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -168,8 +167,8 @@ int vdo_make_packer(struct vdo *vdo, block_count_t bin_count, struct packer **pa
         * bin must have a canceler for which it is waiting, and any canceler will only have
         * canceled one lock holder at a time.
         */
-       result = vdo_allocate_extended(struct packer_bin, MAXIMUM_VDO_USER_VIOS / 2,
-                                      struct vio *, __func__, &packer->canceled_bin);
+       result = vdo_allocate_extended(MAXIMUM_VDO_USER_VIOS / 2, incoming, __func__,
+                                      &packer->canceled_bin);
        if (result != VDO_SUCCESS) {
                vdo_free_packer(packer);
                return result;
index 686eb7d714e60b892357a9430b3dd908cb97d865..a8c7a57516eb8770193a55a8abcac8b67f01c850 100644 (file)
@@ -240,8 +240,7 @@ static int make_pbn_lock_pool(size_t capacity, struct pbn_lock_pool **pool_ptr)
        struct pbn_lock_pool *pool;
        int result;
 
-       result = vdo_allocate_extended(struct pbn_lock_pool, capacity, idle_pbn_lock,
-                                      __func__, &pool);
+       result = vdo_allocate_extended(capacity, locks, __func__, &pool);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -368,8 +367,7 @@ int vdo_make_physical_zones(struct vdo *vdo, struct physical_zones **zones_ptr)
        if (zone_count == 0)
                return VDO_SUCCESS;
 
-       result = vdo_allocate_extended(struct physical_zones, zone_count,
-                                      struct physical_zone, __func__, &zones);
+       result = vdo_allocate_extended(zone_count, zones, __func__, &zones);
        if (result != VDO_SUCCESS)
                return result;
 
index 9bae8256ba4e6ed45f212ac20986c5af245262bb..bb8a878ce4e53566472a382f5d825eaa61da9a04 100644 (file)
@@ -60,8 +60,7 @@ int vdo_make_priority_table(unsigned int max_priority, struct priority_table **t
        if (max_priority > MAX_PRIORITY)
                return UDS_INVALID_ARGUMENT;
 
-       result = vdo_allocate_extended(struct priority_table, max_priority + 1,
-                                      struct bucket, __func__, &table);
+       result = vdo_allocate_extended(max_priority + 1, buckets, __func__, &table);
        if (result != VDO_SUCCESS)
                return result;
 
index 9cc0f0ff1664574e1a456c87e79da6825d607099..6da30396137608996044777549d8b217f31c17df 100644 (file)
@@ -711,10 +711,8 @@ int vdo_decode_recovery_journal(struct recovery_journal_state_7_0 state, nonce_t
        struct recovery_journal *journal;
        int result;
 
-       result = vdo_allocate_extended(struct recovery_journal,
-                                      RECOVERY_JOURNAL_RESERVED_BLOCKS,
-                                      struct recovery_journal_block, __func__,
-                                      &journal);
+       result = vdo_allocate_extended(RECOVERY_JOURNAL_RESERVED_BLOCKS, blocks,
+                                      __func__, &journal);
        if (result != VDO_SUCCESS)
                return result;
 
index 8c006fb3afcf0cba0d8420493c9e847dc2890fbf..e479d35820400280cca99eaf141a529d84dad671 100644 (file)
@@ -1715,9 +1715,7 @@ void vdo_repair(struct vdo_completion *parent)
                vdo_log_warning("Device was dirty, rebuilding reference counts");
        }
 
-       result = vdo_allocate_extended(struct repair_completion, page_count,
-                                      struct vdo_page_completion, __func__,
-                                      &repair);
+       result = vdo_allocate_extended(page_count, page_completions, __func__, &repair);
        if (result != VDO_SUCCESS) {
                vdo_fail_completion(parent, result);
                return;
index ad00afc2c168d897992a49e21a335733b35ecee6..286fc4465a92073a8e56f7307c6ef129c9539dac 100644 (file)
@@ -4266,9 +4266,8 @@ int vdo_decode_slab_depot(struct slab_depot_state_2_0 state, struct vdo *vdo,
                return vdo_log_error_strerror(UDS_CORRUPT_DATA,
                                              "invalid zone count");
 
-       result = vdo_allocate_extended(struct slab_depot,
-                                      vdo->thread_config.physical_zone_count,
-                                      struct block_allocator, __func__, &depot);
+       result = vdo_allocate_extended(vdo->thread_config.physical_zone_count,
+                                      allocators, __func__, &depot);
        if (result != VDO_SUCCESS)
                return result;
 
index 5ffc867d9c5e55bfbe69d98811e0d354e0f48134..cc739d52a70c448e95bc6a7150fada205eb5386f 100644 (file)
@@ -52,8 +52,8 @@ static int create_multi_block_bio(block_count_t size, struct bio **bio_ptr)
        struct bio *bio = NULL;
        int result;
 
-       result = vdo_allocate_extended(struct bio, size + 1, struct bio_vec,
-                                      "bio", &bio);
+       result = vdo_allocate_memory(sizeof(struct bio) + sizeof(struct bio_vec) * (size + 1),
+                                    __alignof__(struct bio), "bio", &bio);
        if (result != VDO_SUCCESS)
                return result;
 
@@ -327,8 +327,7 @@ int make_vio_pool(struct vdo *vdo, size_t pool_size, size_t block_count, thread_
        int result;
        size_t per_vio_size = VDO_BLOCK_SIZE * block_count;
 
-       result = vdo_allocate_extended(struct vio_pool, pool_size, struct pooled_vio,
-                                      __func__, &pool);
+       result = vdo_allocate_extended(pool_size, vios, __func__, &pool);
        if (result != VDO_SUCCESS)
                return result;