kernel: fix FIT partition parser compatibility issues

The uImage.FIT partition parser used to squeeze in FIT partitions in
the range where partition editor tools (fdisk and such) expect the
regular partition. This is confusing people and tools when adding
additional partitions on top of the partition used for OpenWrt's
uImage.FIT.
Instead of squeezing in the additional partitions, rather start with
all uImage.FIT partitions at offset 64.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle 2021-03-31 21:29:26 +01:00
parent 1cc5eb45d5
commit aa0adc8e3c
No known key found for this signature in database
GPG Key ID: 5A8F39C31C3217CA
2 changed files with 18 additions and 65 deletions

View File

@ -141,47 +141,24 @@
dev->gd = gd; dev->gd = gd;
--- a/block/partitions/efi.c --- a/block/partitions/efi.c
+++ b/block/partitions/efi.c +++ b/block/partitions/efi.c
@@ -704,7 +704,7 @@ int efi_partition(struct parsed_partitio @@ -706,6 +706,9 @@ int efi_partition(struct parsed_partitio
{
gpt_header *gpt = NULL;
gpt_entry *ptes = NULL; gpt_entry *ptes = NULL;
- u32 i; u32 i;
+ u32 i, slot = 0;
unsigned ssz = bdev_logical_block_size(state->bdev) / 512; unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
+#ifdef CONFIG_FIT_PARTITION
+ u32 extra_slot = 64;
+#endif
if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
@@ -722,23 +722,30 @@ int efi_partition(struct parsed_partitio kfree(gpt);
u64 size = le64_to_cpu(ptes[i].ending_lba) - @@ -739,6 +742,11 @@ int efi_partition(struct parsed_partitio
le64_to_cpu(ptes[i].starting_lba) + 1ULL;
- if (!is_pte_valid(&ptes[i], last_lba(state->bdev)))
+ if (!is_pte_valid(&ptes[i], last_lba(state->bdev))) {
+ ++slot;
continue;
+ }
- put_partition(state, i+1, start * ssz, size * ssz);
+ put_partition(state, ++slot, start * ssz, size * ssz);
/* If this is a RAID volume, tell md */
if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID))
- state->parts[i + 1].flags = ADDPART_FLAG_RAID;
+ state->parts[slot].flags = ADDPART_FLAG_RAID;
- info = &state->parts[i + 1].info;
+ info = &state->parts[slot].info;
efi_guid_to_str(&ptes[i].unique_partition_guid, info->uuid);
/* Naively convert UTF16-LE to 7 bits. */
label_max = min(ARRAY_SIZE(info->volname) - 1,
ARRAY_SIZE(ptes[i].partition_name)); ARRAY_SIZE(ptes[i].partition_name));
utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname); utf16_le_to_7bit(ptes[i].partition_name, label_max, info->volname);
- state->parts[i + 1].has_info = true; state->parts[i + 1].has_info = true;
+ state->parts[slot].has_info = true;
+#ifdef CONFIG_FIT_PARTITION +#ifdef CONFIG_FIT_PARTITION
+ /* If this is a U-Boot FIT volume it may have subpartitions */ + /* If this is a U-Boot FIT volume it may have subpartitions */
+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID)) + if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &slot, 1); + (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
+#endif +#endif
} }
kfree(ptes); kfree(ptes);

View File

@ -140,48 +140,24 @@
+int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain); +int parse_fit_partitions(struct parsed_partitions *state, u64 start_sector, u64 nr_sectors, int *slot, int add_remain);
--- a/block/partitions/efi.c --- a/block/partitions/efi.c
+++ b/block/partitions/efi.c +++ b/block/partitions/efi.c
@@ -679,7 +679,7 @@ int efi_partition(struct parsed_partitio @@ -681,6 +681,9 @@ int efi_partition(struct parsed_partitio
{
gpt_header *gpt = NULL;
gpt_entry *ptes = NULL; gpt_entry *ptes = NULL;
- u32 i; u32 i;
+ u32 i, slot = 0;
unsigned ssz = bdev_logical_block_size(state->bdev) / 512; unsigned ssz = bdev_logical_block_size(state->bdev) / 512;
+#ifdef CONFIG_FIT_PARTITION
+ u32 extra_slot = 64;
+#endif
if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) { if (!find_valid_gpt(state, &gpt, &ptes) || !gpt || !ptes) {
@@ -698,16 +698,18 @@ int efi_partition(struct parsed_partitio kfree(gpt);
u64 size = le64_to_cpu(ptes[i].ending_lba) - @@ -722,6 +725,11 @@ int efi_partition(struct parsed_partitio
le64_to_cpu(ptes[i].starting_lba) + 1ULL;
- if (!is_pte_valid(&ptes[i], last_lba(state->bdev)))
+ if (!is_pte_valid(&ptes[i], last_lba(state->bdev))) {
+ ++slot;
continue;
+ }
- put_partition(state, i+1, start * ssz, size * ssz);
+ put_partition(state, ++slot, start * ssz, size * ssz);
/* If this is a RAID volume, tell md */
if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_RAID_GUID))
- state->parts[i + 1].flags = ADDPART_FLAG_RAID;
+ state->parts[slot].flags = ADDPART_FLAG_RAID;
- info = &state->parts[i + 1].info;
+ info = &state->parts[slot].info;
efi_guid_to_str(&ptes[i].unique_partition_guid, info->uuid);
/* Naively convert UTF16-LE to 7 bits. */
@@ -721,7 +723,12 @@ int efi_partition(struct parsed_partitio
info->volname[label_count] = c;
label_count++; label_count++;
} }
- state->parts[i + 1].has_info = true; state->parts[i + 1].has_info = true;
+ state->parts[slot].has_info = true;
+#ifdef CONFIG_FIT_PARTITION +#ifdef CONFIG_FIT_PARTITION
+ /* If this is a U-Boot FIT volume it may have subpartitions */ + /* If this is a U-Boot FIT volume it may have subpartitions */
+ if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID)) + if (!efi_guidcmp(ptes[i].partition_type_guid, PARTITION_LINUX_FIT_GUID))
+ (void) parse_fit_partitions(state, start * ssz, size * ssz, &slot, 1); + (void) parse_fit_partitions(state, start * ssz, size * ssz, &extra_slot, 1);
+#endif +#endif
} }
kfree(ptes); kfree(ptes);