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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
#include <linux/cache.h>
#include <linux/io.h> /* for PAGE_SIZE */
+#include <linux/overflow.h>
#include "permassert.h"
#include "thread-registry.h"
__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
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;
* 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;
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;
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;
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;
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;
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;
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;
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;
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;