diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2024-02-19 09:31:31 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2024-02-20 11:46:30 +0100 |
commit | 57392a862d40a31ac463ad0bd8c158e23a0d6b4a (patch) | |
tree | 4e5fb27d0cef62c4b970b8daf1ec57e5cdd20813 | |
parent | 1018f6c694f0561028af3496530316e9db32e3a4 (diff) | |
download | barebox-57392a862d40.tar.gz barebox-57392a862d40.tar.xz |
partition: allocate struct partition in parser
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.
Link: https://lore.barebox.org/20240219083140.2713047-4-s.hauer@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | common/partitions.c | 12 | ||||
-rw-r--r-- | common/partitions/dos.c | 56 | ||||
-rw-r--r-- | common/partitions/efi.c | 13 | ||||
-rw-r--r-- | 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 @@ out: 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 @@ out: 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 { |