From 6d69c7183ec30e245834ed04b8755e3bc938b455 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sat, 21 Jan 2012 12:50:59 +0100 Subject: [PATCH] libparted: gpt: rewrite even a 9-partition-entry table properly The vast majority of GPT partition tables have 128 PTEs (partition table entries. However, zfs-related ones have only 9, and when rewriting one (which can happen only in interactive mode), parted would fail to write the full PTE array whenever the PTE array size was not a multiple of the sector size. This fixes the same type of bug as v3.0-45-gce85c51. * libparted/labels/gpt.c (gpt_write): When computing how many sectors to write for the PTE array, round up rather than truncating. This matters only when n_PTEs * 128 is not a multiple of the sector size. For details on how to reproduce see the test or http://thread.gmane.org/gmane.comp.gnu.parted.bugs/10691/focus=10695 * NEWS (Bug fixes): Mention it. --- NEWS | 8 ++++++++ libparted/labels/gpt.c | 9 ++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 7584c56..9d189dc 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ GNU parted NEWS -*- outline -*- parted has improved support for partitionable loopback devices ** Bug fixes + The msdos partition table claimed a maximum partition count of 16 but would allow you to go beyond that. This resulted in the kernel not being informed of those partitions. Corrected to enforce the @@ -19,6 +20,13 @@ GNU parted NEWS -*- outline -*- of "Error: ...unrecognised disk label" and "Error:... both GPT primary and backup partition tables are corrupted". + libparted: given a GPT table with a partition table array of length, say 9, + (usually, there are at least 128 entries) and when run in interactive mode + with the backup header not at the end of the device where it belongs, parted + would offer to fix it by moving the backup header to the end. If you + accepted, parted could corrupt both headers, truncating their on-disk + PTE arrays. Now, parted handles this case. + libparted: gpt_disk_duplicate now copies the flags over to the new disk object. Previously the flags would be undefined. diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c index c74ff51..bad9ed4 100644 --- a/libparted/labels/gpt.c +++ b/libparted/labels/gpt.c @@ -1236,8 +1236,9 @@ gpt_write (const PedDisk *disk) free (pth_raw); if (!write_ok) goto error_free_ptes; - if (!ped_device_write (disk->dev, ptes, 2, - ptes_bytes / disk->dev->sector_size)) + size_t ss = disk->dev->sector_size; + PedSector ptes_sectors = (ptes_bytes + ss - 1) / ss; + if (!ped_device_write (disk->dev, ptes, 2, ptes_sectors)) goto error_free_ptes; /* Write Alternate PTH & PTEs */ @@ -1253,9 +1254,7 @@ gpt_write (const PedDisk *disk) if (!write_ok) goto error_free_ptes; if (!ped_device_write (disk->dev, ptes, - disk->dev->length - 1 - - ptes_bytes / disk->dev->sector_size, - ptes_bytes / disk->dev->sector_size)) + disk->dev->length - 1 - ptes_sectors, ptes_sectors)) goto error_free_ptes; free (ptes); -- 2.11.0