[PATCH 20/26] partition: support non-512 byte sectors
Ahmad Fatoum <[email protected]> Fri, 26 Jun 2026 10:42:31 +0200
| Newsgroups | org.infradead.lists.barebox |
|---|---|
| Message-ID | <[email protected]> |
Partition parsing still mixed LBAs with hardcoded 512-byte sectors all over the place. Carry the block device logical block size through all read paths. Assisted-by: Codex:gpt-5.5 Signed-off-by: Ahmad Fatoum <[email protected]> --- common/partitions.c | 55 +++++++++++++++++++++++++++-------------- common/partitions/dos.c | 4 +-- common/partitions/efi.c | 21 ++++++---------- include/partitions.h | 2 +- 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/common/partitions.c b/common/partitions.c index 8637b54b1708..617c2770eadf 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -36,10 +36,10 @@ static int register_one_partition(struct block_device *blk, struct partition *pa char *partition_name; int ret; struct cdev *cdev; - struct devfs_partition partinfo = { - .offset = part->first_sec * SECTOR_SIZE, - .size = part->size * SECTOR_SIZE, - }; + struct devfs_partition partinfo = {}; + + partinfo.offset = part->first_sec * BLOCKSIZE(blk); + partinfo.size = part->size * BLOCKSIZE(blk); partition_name = xasprintf("%s.%d", blk->cdev.name, part->num); @@ -92,24 +92,26 @@ static int remove_one_partition(struct block_device *blk, int no) return ret; } -static struct partition_parser *partition_parser_get_by_filetype(uint8_t *buf) +static struct partition_parser *partition_parser_get_by_filetype(uint8_t *buf, + unsigned int blocksize) { enum filetype type; struct partition_parser *parser; /* first new partition table as EFI GPT */ - type = file_detect_partition_table(buf, SECTOR_SIZE * 2, SECTOR_SIZE); + type = file_detect_partition_table(buf, blocksize * 2, blocksize); list_for_each_entry(parser, &partition_parser_list, list) { if (parser->type == type) return parser; } - /* if not parser found search for old one - * so if EFI GPT not enable take it as MBR - * useful for compatibility + /* If no parser found search for old one, so if EFI GPT i + * not enabled, probe for MBR. useful for compatibility. + * 512 is hardcoded here as the MBR detection is not + * block-size dependent. */ - type = file_detect_partition_table(buf, SECTOR_SIZE, SECTOR_SIZE); + type = file_detect_partition_table(buf, 512, 512); if (type == filetype_fat && !is_fat_boot_sector(buf)) type = filetype_mbr; @@ -150,9 +152,11 @@ struct partition_desc *partition_table_read(struct block_device *blk) struct partition_parser *parser; struct partition_desc *pdesc = NULL; uint8_t *buf; + unsigned int blocksize; int ret; - buf = malloc(2 * SECTOR_SIZE); + blocksize = BLOCKSIZE(blk); + buf = malloc(2 * blocksize); ret = block_read(blk, buf, 0, 2); if (ret != 0) { @@ -160,7 +164,7 @@ struct partition_desc *partition_table_read(struct block_device *blk) goto err; } - parser = partition_parser_get_by_filetype(buf); + parser = partition_parser_get_by_filetype(buf, blocksize); if (!parser) goto err; @@ -187,7 +191,7 @@ bool partition_is_free(struct partition_desc *pdesc, uint64_t start, uint64_t si { struct partition *p; - if (start < PARTITION_ALIGN_SECTORS) + if (start < partition_align_lba(pdesc->blk)) return false; if (start + size >= pdesc->blk->num_blocks) @@ -204,7 +208,7 @@ bool partition_is_free(struct partition_desc *pdesc, uint64_t start, uint64_t si int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, uint64_t *start) { struct partition *p; - uint64_t align = PARTITION_ALIGN_SECTORS; + uint64_t align = partition_align_lba(pdesc->blk); uint64_t min_sec; min_sec = max(align, partition_first_usable_lba(pdesc->blk)); @@ -371,19 +375,25 @@ static int fuzz_partition_table_parser(struct block_device *ramdisk) struct partition *part; int rc = 0; struct partition_parser *parser; - u8 buf[2 * SECTOR_SIZE] __aligned(8); + u8 *buf; + unsigned int blocksize; + + blocksize = BLOCKSIZE(ramdisk); + buf = malloc(2 * blocksize); + if (!buf) + return 0; rc = block_read(ramdisk, buf, 0, 2); if (rc != 0) - return 0; + goto out; - parser = partition_parser_get_by_filetype(buf); + parser = partition_parser_get_by_filetype(buf, blocksize); if (!parser) - return 0; + goto out; pdesc = parser->parse(buf, ramdisk); if (!pdesc) - return 0; + goto out; pdesc->parser = parser; @@ -394,6 +404,8 @@ static int fuzz_partition_table_parser(struct block_device *ramdisk) partition_table_free(pdesc); +out: + free(buf); return 0; } fuzz_test_ramdisk("partitions", fuzz_partition_table_parser); @@ -430,6 +442,11 @@ sector_t partition_first_usable_lba(const struct block_device *blk) return blockdevice_round_nblocks(blk, first_partition_offset); } +sector_t partition_align_lba(const struct block_device *blk) +{ + return blockdevice_round_nblocks(blk, PARTITION_ALIGN_SIZE); +} + static int set_first_partition_offset(struct param_d *p, void *priv) { if (first_partition_offset < MIN_SECTOR_SIZE) { diff --git a/common/partitions/dos.c b/common/partitions/dos.c index 1526b97dec67..e5286cb6eb1f 100644 --- a/common/partitions/dos.c +++ b/common/partitions/dos.c @@ -60,7 +60,7 @@ static inline int is_extended_partition(struct partition *p) static void *read_mbr(struct block_device *blk) { - void *buf = xmalloc(SECTOR_SIZE); + void *buf = xmalloc(BLOCKSIZE(blk)); int ret; ret = block_read(blk, buf, 0, 1); @@ -126,7 +126,7 @@ static int dos_get_disk_signature(struct param_d *p, void *_priv) static void dos_extended_partition(struct block_device *blk, struct dos_partition_desc *dpd, struct partition *partition, uint32_t signature) { - uint8_t *buf = xmalloc(SECTOR_SIZE); + uint8_t *buf = xmalloc(BLOCKSIZE(blk)); uint32_t ebr_sector = partition->first_sec; struct partition_entry *table = (struct partition_entry *)&buf[0x1be]; unsigned partno = 4; diff --git a/common/partitions/efi.c b/common/partitions/efi.c index 295c26a5a491..33d9a1df9e83 100644 --- a/common/partitions/efi.c +++ b/common/partitions/efi.c @@ -199,19 +199,20 @@ static gpt_entry *alloc_read_gpt_entries(struct block_device *blk, { u32 count = 0; gpt_entry *pte = NULL; - unsigned long from, size; + unsigned long from; + blkcnt_t size; int ret; count = compute_partitions_entries_size(pgpt_head); if (!count) return NULL; - pte = calloc(count, 1); + pte = calloc(blockdevice_round_block_nbytes(blk, count), 1); if (!pte) return NULL; from = le64_to_cpu(pgpt_head->partition_entry_lba); - size = count / GPT_BLOCK_SIZE; + size = blockdevice_round_nblocks(blk, count); ret = block_read(blk, pte, from, size); if (ret) { free(pte); @@ -220,12 +221,6 @@ static gpt_entry *alloc_read_gpt_entries(struct block_device *blk, return pte; } -static inline unsigned short bdev_logical_block_size(struct block_device -*bdev) -{ - return SECTOR_SIZE; -} - /** * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk * @state @@ -239,7 +234,7 @@ static gpt_header *alloc_read_gpt_header(struct block_device *blk, u64 lba) { gpt_header *gpt; - unsigned ssz = bdev_logical_block_size(blk); + unsigned ssz = BLOCKSIZE(blk); int ret; gpt = calloc(ssz, 1); @@ -286,7 +281,7 @@ static int is_gpt_valid(struct block_device *blk, u64 lba, } if (le32_to_cpu((*gpt)->header_size) < sizeof(struct _gpt_header) || - le32_to_cpu((*gpt)->header_size) > bdev_logical_block_size(blk)) + le32_to_cpu((*gpt)->header_size) > BLOCKSIZE(blk)) goto fail; /* Check the GUID Partition Table CRC */ @@ -505,8 +500,8 @@ static int find_valid_gpt(struct efi_partition_desc *epd, void *buf) lastlba = last_lba(blk); if (force_gpt) { /* This will be added to the EFI Spec. per Intel after v1.02. */ - if (file_detect_partition_table(buf, SECTOR_SIZE * 2, - SECTOR_SIZE) != filetype_gpt) + if (file_detect_partition_table(buf, 2 * BLOCKSIZE(blk), + BLOCKSIZE(blk)) != filetype_gpt) goto fail; } diff --git a/include/partitions.h b/include/partitions.h index 398813eca58c..7eb8b1e6e228 100644 --- a/include/partitions.h +++ b/include/partitions.h @@ -58,7 +58,6 @@ struct partition_parser { }; #define PARTITION_ALIGN_SIZE SZ_1M -#define PARTITION_ALIGN_SECTORS (PARTITION_ALIGN_SIZE >> SECTOR_SHIFT) void partition_desc_init(struct partition_desc *pd, struct block_device *blk); int partition_parser_register(struct partition_parser *p); @@ -72,5 +71,6 @@ void partition_table_free(struct partition_desc *pdesc); bool partition_is_free(struct partition_desc *pdesc, uint64_t start, uint64_t size); int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, uint64_t *start); sector_t partition_first_usable_lba(const struct block_device *blk); +sector_t partition_align_lba(const struct block_device *blk); #endif /* __PARTITIONS_PARSER_H__ */ -- 2.47.3