On 12/3/25 4:19 PM, Sascha Hauer wrote:
> 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]>

Reviewed-by: Ahmad Fatoum <[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;
>  }
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |


Reply via email to