libfdisk: Include table-length in first-lba checks

Otherwise, sfdisk would error out on its own dump, as first-lba would be
earlier than "plausible" assuming the default table size.

This is because it did not look for `table-length` when using an sfdisk
script. This means that using `--dump` on a valid image, could not be
unserialized back into a valid image.

This is helpful in exotic situations, where a partition has to be
created earlier than the conventional "first-lba" (2048). For example,
on Allwinner A64 boards, where a firmware is stored at LBA16. With this
it is possible to ask for `first-lba` at or earlier than 16, by reducing
the number of entries to e.g. 48.
This commit is contained in:
Samuel Dionne-Riel 2021-04-17 02:17:53 -04:00
parent 1c75a85101
commit fb64d93288
1 changed files with 23 additions and 13 deletions

View File

@ -747,7 +747,7 @@ static int count_first_last_lba(struct fdisk_context *cxt,
{
int rc = 0;
uint64_t flba = 0, llba = 0;
uint32_t nents;
uint64_t nents = GPT_NPARTITIONS;
assert(cxt);
assert(first);
@ -755,18 +755,28 @@ static int count_first_last_lba(struct fdisk_context *cxt,
*first = *last = 0;
/* The default is GPT_NPARTITIONS, if the device is not large enough
* than reduce this number of partitions and try to recalculate it
* again, until we get something useful or return error.
*/
for (nents = GPT_NPARTITIONS; nents > 0; nents--) {
rc = gpt_calculate_last_lba(NULL, nents, &llba, cxt);
if (rc == 0)
rc = gpt_calculate_first_lba(NULL, nents, &flba, cxt);
if (llba < flba)
rc = -ENOSPC;
else if (rc == 0)
break;
/* Get the table length from the script, if given */
if (cxt->script) {
rc = get_script_u64(cxt, &nents, "table-length");
if (rc < 0)
return rc;
}
/* The table length was not changed by the script, compute it. */
if (flba == 0) {
/* If the device is not large enough reduce this number of
* partitions and try to recalculate it again, until we get
* something useful or return error.
*/
for (; nents > 0; nents--) {
rc = gpt_calculate_last_lba(NULL, nents, &llba, cxt);
if (rc == 0)
rc = gpt_calculate_first_lba(NULL, nents, &flba, cxt);
if (llba < flba)
rc = -ENOSPC;
else if (rc == 0)
break;
}
}
if (rc)