In preparation for writing the inactive GPT first factor out a function which either writes the primary or alternate GPT based on a boolean argument.
Signed-off-by: Sascha Hauer <[email protected]> --- common/partitions/efi.c | 92 ++++++++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 39 deletions(-) diff --git a/common/partitions/efi.c b/common/partitions/efi.c index 76c5393dddb04e2966d3a4b4478d5085f008d935..8da62acf36646b62ff2fac25673adbc48650d299 100644 --- a/common/partitions/efi.c +++ b/common/partitions/efi.c @@ -740,75 +740,89 @@ static int efi_protective_mbr(struct block_device *blk) return ret; } -static __maybe_unused int efi_partition_write(struct partition_desc *pd) +static int __efi_partition_write(struct efi_partition_desc *epd, bool primary) { - struct block_device *blk = pd->blk; - struct efi_partition_desc *epd = container_of(pd, struct efi_partition_desc, pd); - gpt_header *gpt = epd->gpt, *altgpt; + struct block_device *blk = epd->pd.blk; + gpt_header *gpt; + unsigned int count, size; + uint64_t my_lba, partition_entry_lba; int ret; - uint32_t count; - uint64_t from, size; - if (le32_to_cpu(gpt->num_partition_entries) != 128) { - /* - * This is not yet properly implemented. At least writing of the - * alternative GPT is not correctly implemented for this case as - * we can't assume that the partition entries are written at - * last_lba() - 32, we would have to calculate that from the number - * of partition entries. - */ - pr_err("num_partition_entries is != 128. This is not yet supported for writing\n"); - return -EINVAL; - } + gpt = xmemdup(epd->gpt, SECTOR_SIZE); count = le32_to_cpu(gpt->num_partition_entries) * le32_to_cpu(gpt->sizeof_partition_entry); - gpt->my_lba = cpu_to_le64(1); - gpt->alternate_lba = cpu_to_le64(last_lba(blk)); + size = count / GPT_BLOCK_SIZE; + + if (primary) { + my_lba = 1; + partition_entry_lba = le64_to_cpu(gpt->partition_entry_lba); + gpt->alternate_lba = cpu_to_le64(last_lba(blk)); + } else { + my_lba = last_lba(blk); + partition_entry_lba = last_lba(blk) - 32; + gpt->alternate_lba = cpu_to_le64(1); + } + + gpt->my_lba = cpu_to_le64(my_lba); + gpt->partition_entry_lba = cpu_to_le64(partition_entry_lba); gpt->partition_entry_array_crc32 = cpu_to_le32(efi_crc32( (const unsigned char *)epd->ptes, count)); gpt->header_crc32 = 0; gpt->header_crc32 = cpu_to_le32(efi_crc32((const unsigned char *)gpt, le32_to_cpu(gpt->header_size))); - ret = efi_protective_mbr(blk); + ret = block_write(blk, gpt, my_lba, 1); if (ret) - return ret; + goto err_block_write; - ret = block_write(blk, gpt, 1, 1); + ret = block_write(blk, epd->ptes, partition_entry_lba, size); if (ret) goto err_block_write; - from = le64_to_cpu(gpt->partition_entry_lba); - size = count / GPT_BLOCK_SIZE; +err_block_write: + free(gpt); - ret = block_write(blk, epd->ptes, from, size); - if (ret) - goto err_block_write; + return ret; +} - altgpt = xmemdup(gpt, SECTOR_SIZE); +static __maybe_unused int efi_partition_write(struct partition_desc *pd) +{ + struct block_device *blk = pd->blk; + struct efi_partition_desc *epd = container_of(pd, struct efi_partition_desc, pd); + gpt_header *gpt = epd->gpt; + int ret; - altgpt->alternate_lba = cpu_to_le64(1); - altgpt->my_lba = cpu_to_le64(last_lba(blk)); - altgpt->partition_entry_lba = cpu_to_le64(last_lba(blk) - 32); - altgpt->header_crc32 = 0; - altgpt->header_crc32 = cpu_to_le32(efi_crc32((const unsigned char *)altgpt, - le32_to_cpu(altgpt->header_size))); - ret = block_write(blk, altgpt, last_lba(blk), 1); + if (le32_to_cpu(gpt->num_partition_entries) != 128) { + /* + * This is not yet properly implemented. At least writing of the + * alternative GPT is not correctly implemented for this case as + * we can't assume that the partition entries are written at + * last_lba() - 32, we would have to calculate that from the number + * of partition entries. + */ + pr_err("num_partition_entries is != 128. This is not yet supported for writing\n"); + return -EINVAL; + } - free(altgpt); + ret = efi_protective_mbr(blk); + if (ret) + return ret; + ret = __efi_partition_write(epd, true); if (ret) goto err_block_write; - ret = block_write(blk, epd->ptes, last_lba(blk) - 32, size); + + ret = __efi_partition_write(epd, false); if (ret) goto err_block_write; - return 0; + ret = 0; err_block_write: - pr_err("Cannot write to block device: %pe\n", ERR_PTR(ret)); + if (ret) + pr_err("Cannot write to block device: %pe\n", ERR_PTR(ret)); return ret; } -- 2.47.3
