Allocate struct partition in the parser rather than in the core partition code. Doing so allows the parser to embed struct partition in an implementation specific struct type. Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx> --- common/partitions.c | 12 ++++---- common/partitions/dos.c | 56 ++++++++++++++++++++++---------------- common/partitions/efi.c | 13 +++++++-- common/partitions/parser.h | 5 ++-- 4 files changed, 51 insertions(+), 35 deletions(-) diff --git a/common/partitions.c b/common/partitions.c index 05ebde7ca3..0d8c2849ab 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -27,8 +27,7 @@ static LIST_HEAD(partition_parser_list); * @param no Partition number * @return 0 on success */ -static int register_one_partition(struct block_device *blk, - struct partition *part, int no) +static int register_one_partition(struct block_device *blk, struct partition *part) { char *partition_name; int ret; @@ -38,7 +37,7 @@ static int register_one_partition(struct block_device *blk, .size = part->size * SECTOR_SIZE, }; - partition_name = basprintf("%s.%d", blk->cdev.name, no); + partition_name = basprintf("%s.%d", blk->cdev.name, part->num); if (!partition_name) return -ENOMEM; @@ -117,6 +116,7 @@ int parse_partition_table(struct block_device *blk) int i; int rc = 0; struct partition_parser *parser; + struct partition *part; uint8_t *buf; buf = malloc(2 * SECTOR_SIZE); @@ -135,12 +135,12 @@ int parse_partition_table(struct block_device *blk) if (!pdesc) goto on_error; - if (!pdesc->used_entries) + if (list_empty(&pdesc->partitions)) goto on_error; /* at least one partition description found */ - for (i = 0; i < pdesc->used_entries; i++) { - rc = register_one_partition(blk, &pdesc->parts[i], i); + list_for_each_entry(part, &pdesc->partitions, list) { + rc = register_one_partition(blk, part); if (rc != 0) dev_err(blk->dev, "Failed to register partition %d on %s (%d)\n", diff --git a/common/partitions/dos.c b/common/partitions/dos.c index 01a251201e..7ca3c4e37e 100644 --- a/common/partitions/dos.c +++ b/common/partitions/dos.c @@ -113,10 +113,10 @@ static void dos_extended_partition(struct block_device *blk, struct partition_de uint32_t ebr_sector = partition->first_sec; struct partition_entry *table = (struct partition_entry *)&buf[0x1be]; unsigned partno = 5; + struct partition *pentry; - while (pd->used_entries < ARRAY_SIZE(pd->parts)) { + while (1) { int rc, i; - int n = pd->used_entries; dev_dbg(blk->dev, "expect EBR in sector %x\n", ebr_sector); @@ -139,15 +139,19 @@ static void dos_extended_partition(struct block_device *blk, struct partition_de } /* /sanity checks */ + pentry = xzalloc(sizeof(*pentry)); + /* the first entry defines the extended partition */ - pd->parts[n].first_sec = ebr_sector + + pentry->first_sec = ebr_sector + get_unaligned_le32(&table[0].partition_start); - pd->parts[n].size = get_unaligned_le32(&table[0].partition_size); - pd->parts[n].dos_partition_type = table[0].type; + pentry->size = get_unaligned_le32(&table[0].partition_size); + pentry->dos_partition_type = table[0].type; + pentry->num = partno; if (signature) - sprintf(pd->parts[n].partuuid, "%08x-%02u", + sprintf(pentry->partuuid, "%08x-%02u", signature, partno); - pd->used_entries++; + + list_add_tail(&pentry->list, &pd->partitions); partno++; /* the second entry defines the start of the next ebr if != 0 */ @@ -174,7 +178,7 @@ static void dos_extended_partition(struct block_device *blk, struct partition_de static struct partition_desc *dos_partition(void *buf, struct block_device *blk) { struct partition_entry *table; - struct partition pentry; + struct partition *pentry; struct partition *extended_partition = NULL; uint8_t *buffer = buf; int i; @@ -190,33 +194,30 @@ static struct partition_desc *dos_partition(void *buf, struct block_device *blk) table = (struct partition_entry *)&buffer[446]; pd = xzalloc(sizeof(*pd)); + INIT_LIST_HEAD(&pd->partitions); for (i = 0; i < 4; i++) { - int n; + uint64_t first_sec = get_unaligned_le32(&table[i].partition_start); - pentry.first_sec = get_unaligned_le32(&table[i].partition_start); - pentry.size = get_unaligned_le32(&table[i].partition_size); - pentry.dos_partition_type = table[i].type; - - if (pentry.first_sec == 0) { + if (first_sec == 0) { dev_dbg(blk->dev, "Skipping empty partition %d\n", i); continue; } - n = pd->used_entries; - pd->parts[n].first_sec = pentry.first_sec; - pd->parts[n].size = pentry.size; - pd->parts[n].dos_partition_type = pentry.dos_partition_type; + pentry = xzalloc(sizeof(*pentry)); + + pentry->first_sec = first_sec; + pentry->size = get_unaligned_le32(&table[i].partition_size); + pentry->dos_partition_type = table[i].type; + if (signature) - sprintf(pd->parts[n].partuuid, "%08x-%02d", - signature, i + 1); - pd->used_entries++; + sprintf(pentry->partuuid, "%08x-%02d", signature, i + 1); - if (is_extended_partition(&pentry)) { - pd->parts[n].size = 2; + if (is_extended_partition(pentry)) { + pentry->size = 2; if (!extended_partition) - extended_partition = &pd->parts[n]; + extended_partition = pentry; else /* * An DOS MBR must only contain a single @@ -225,6 +226,8 @@ static struct partition_desc *dos_partition(void *buf, struct block_device *blk) */ dev_warn(blk->dev, "Skipping additional extended partition\n"); } + + list_add_tail(&pentry->list, &pd->partitions); } if (extended_partition) @@ -252,6 +255,11 @@ static struct partition_desc *dos_partition(void *buf, struct block_device *blk) static void dos_partition_free(struct partition_desc *pd) { + struct partition *part, *tmp; + + list_for_each_entry_safe(part, tmp, &pd->partitions, list) + free(part); + free(pd); } diff --git a/common/partitions/efi.c b/common/partitions/efi.c index effe512949..5612f6261b 100644 --- a/common/partitions/efi.c +++ b/common/partitions/efi.c @@ -438,7 +438,7 @@ static struct partition_desc *efi_partition(void *buf, struct block_device *blk) int i = 0; int nb_part; struct partition *pentry; - struct partition_desc *pd; + struct partition_desc *pd = NULL; if (!find_valid_gpt(buf, blk, &gpt, &ptes) || !gpt || !ptes) goto out; @@ -457,6 +457,7 @@ static struct partition_desc *efi_partition(void *buf, struct block_device *blk) } pd = xzalloc(sizeof(*pd)); + INIT_LIST_HEAD(&pd->partitions); for (i = 0; i < nb_part; i++) { if (!is_pte_valid(&ptes[i], last_lba(blk))) { @@ -464,14 +465,15 @@ static struct partition_desc *efi_partition(void *buf, struct block_device *blk) continue; } - pentry = &pd->parts[pd->used_entries]; + pentry = xzalloc(sizeof(*pentry)); pentry->first_sec = le64_to_cpu(ptes[i].starting_lba); pentry->size = le64_to_cpu(ptes[i].ending_lba) - pentry->first_sec; pentry->size++; part_set_efi_name(&ptes[i], pentry->name); snprintf(pentry->partuuid, sizeof(pentry->partuuid), "%pUl", &ptes[i].unique_partition_guid); pentry->typeuuid = ptes[i].partition_type_guid; - pd->used_entries++; + pentry->num = i; + list_add_tail(&pentry->list, &pd->partitions); } out: kfree(gpt); @@ -482,6 +484,11 @@ static struct partition_desc *efi_partition(void *buf, struct block_device *blk) static void efi_partition_free(struct partition_desc *pd) { + struct partition *part, *tmp; + + list_for_each_entry_safe(part, tmp, &pd->partitions, list) + free(part); + free(pd); } diff --git a/common/partitions/parser.h b/common/partitions/parser.h index 3eec2cdb21..ab593109e6 100644 --- a/common/partitions/parser.h +++ b/common/partitions/parser.h @@ -24,11 +24,12 @@ struct partition { u8 dos_partition_type; guid_t typeuuid; }; + struct list_head list; + int num; }; struct partition_desc { - int used_entries; - struct partition parts[MAX_PARTITION]; + struct list_head partitions; }; struct partition_parser { -- 2.39.2