Skip to content

Conversation

@ya-mouse
Copy link
Contributor

The gpt_fill_header() function was incorrectly calculating the last_usable_lba value using a hardcoded assumption about the partition table entry (PTE) area size. This caused incorrect backup GPT placement on disks with non-512-byte sector sizes.

The GPT specification requires 128 partition entries × 128 bytes = 16384 bytes for the partition entry array. For 512-byte sectors this requires 32 sectors, but for 4096-byte sectors only 4 sectors are needed.

Introduce a local pte_sectors variable that dynamically calculates the number of sectors required for the partition entries based on the actual block size:

pte_sectors = DIV_ROUND_UP(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
                           desc->blksz);

This ensures:

  • last_usable_lba correctly reserves space for backup GPT header (1 block) plus backup partition entries (pte_sectors blocks)
  • first_usable_lba correctly accounts for the primary partition entries starting at partition_entry_lba

The fix is essential for:

  • Disks with 4K native sector size (i.e. UFS flashes)
  • Proper GPT compliance across all sector size configurations

Change-Id: faf3cb2e-056d-458d-8abe-61edf2f40384

@ya-mouse ya-mouse requested a review from alchark January 20, 2026 08:02

if (offset > (last_usable_lba + 1)) {
log_debug("Partitions layout exceeds disk size\n");
log_debug("Partitions layout exceeds disk size: %lu > %lu\n", offset, last_usable_lba + 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long line, please wrap at the first comma

gpt_h->alternate_lba = cpu_to_le64(desc->lba - 1);
gpt_h->last_usable_lba = cpu_to_le64(desc->lba - 34);
/* Reserve space for backup GPT header (1) + backup partition entries */
gpt_h->last_usable_lba = cpu_to_le64(desc->lba - pte_sectors - 1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-32 - 1 != -34
Please check

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay. Seems like one sector lost for backup header.

The gpt_fill_header() function was incorrectly calculating the
last_usable_lba value using a hardcoded assumption about the partition
table entry (PTE) area size. This caused incorrect backup GPT placement
on disks with non-512-byte sector sizes.

The GPT specification requires 128 partition entries × 128 bytes = 16384
bytes for the partition entry array. For 512-byte sectors this requires
32 sectors, but for 4096-byte sectors only 4 sectors are needed.

Introduce a local pte_sectors variable that dynamically calculates the
number of sectors required for the partition entries based on the actual
block size:

    pte_sectors = DIV_ROUND_UP(GPT_ENTRY_NUMBERS * sizeof(gpt_entry),
                               desc->blksz);

This ensures:
- last_usable_lba correctly reserves space for backup GPT header (1 block)
  plus backup partition entries (pte_sectors blocks)
- first_usable_lba correctly accounts for the primary partition entries
  starting at partition_entry_lba

The fix is essential for:
- Disks with 4K native sector size (i.e. UFS flashes)
- Proper GPT compliance across all sector size configurations

Change-Id: faf3cb2e-056d-458d-8abe-61edf2f40384
Signed-off-by: Anton Burticica <mouse@ya.ru>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants