parted/0088-libparted-Fix-check-for-backup-header-location.patch
Brian C. Lane 0b7af917e2 - Rebase on new upstream master commit cc382c3
- Drop patches incorporated into upstream
- Still adds the various DASD patches
2014-04-08 11:46:37 -07:00

88 lines
3.4 KiB
Diff

From 503e98c49fa06512fd1b0318aba6ee5de6cbd7b4 Mon Sep 17 00:00:00 2001
From: "Brian C. Lane" <bcl@redhat.com>
Date: Tue, 8 Apr 2014 10:54:27 -0700
Subject: [PATCH 88/91] libparted: Fix check for backup header location
Add a couple of helper functions for calculating the partition table
entry size (in sectors) and for guessing the end of the disk based on
the LastUsableLBA and the Partition Table Entry size.
The backup header should be either at the end of the disk, or at what
the primary header thinks is the end of the disk. Prompt to fix the
backup header if it is located any other place.
* libparted/labels/gpt.c (_ptes_sectors): New function
(_hdr_disk_end): New function
(gpt_read): Use new function to test for pri's idea of end of disk
---
libparted/labels/gpt.c | 38 +++++++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index 42b0360..c5dea2f 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -693,6 +693,29 @@ _header_is_valid (PedDisk const *disk, GuidPartitionTableHeader_t *gpt,
return crc == PED_LE32_TO_CPU (origcrc);
}
+/* Return the number of sectors that should be used by the
+ * partition entry table.
+ */
+static PedSector
+_ptes_sectors(PedDisk const *disk, GuidPartitionTableHeader_t const *gpt)
+{
+ size_t ptes_bytes = PED_LE32_TO_CPU (gpt->SizeOfPartitionEntry) *
+ PED_LE32_TO_CPU (gpt->NumberOfPartitionEntries);
+ /* Minimum amount of space reserved is 128 128 byte entries */
+ if (ptes_bytes < 128*128)
+ ptes_bytes = 128*128;
+ return ped_div_round_up (ptes_bytes, disk->dev->sector_size);
+}
+
+/* Return the header's idea of the last sector of the disk
+ * based on LastUsableLBA and the Partition Entry table.
+ */
+static PedSector
+_hdr_disk_end(PedDisk const *disk, GuidPartitionTableHeader_t const *gpt)
+{
+ return PED_LE64_TO_CPU (gpt->LastUsableLBA) + 1 + _ptes_sectors(disk, gpt);
+}
+
static int
_parse_header (PedDisk *disk, const GuidPartitionTableHeader_t *gpt,
int *update_needed)
@@ -985,13 +1008,14 @@ gpt_read (PedDisk *disk)
{
/* Both are valid. */
#ifndef DISCOVER_ONLY
- PedSector gpt_disk_end = PED_LE64_TO_CPU (primary_gpt->LastUsableLBA) + 1;
- gpt_disk_end += ((PedSector) (PED_LE32_TO_CPU (primary_gpt->NumberOfPartitionEntries)) *
- (PedSector) (PED_LE32_TO_CPU (primary_gpt->SizeOfPartitionEntry)) /
- disk->dev->sector_size);
-
+ /* The backup header must be at the end of the disk, or at what the primary
+ * header thinks is the end of the disk.
+ */
gpt_disk_data->AlternateLBA = PED_LE64_TO_CPU (primary_gpt->AlternateLBA);
- if (PED_LE64_TO_CPU (primary_gpt->AlternateLBA) != gpt_disk_end)
+ PedSector pri_disk_end = _hdr_disk_end(disk, primary_gpt);
+
+ if (gpt_disk_data->AlternateLBA != disk->dev->length -1 &&
+ gpt_disk_data->AlternateLBA != pri_disk_end)
{
if (ped_exception_throw
(PED_EXCEPTION_ERROR,
@@ -1002,7 +1026,7 @@ gpt_read (PedDisk *disk)
{
ptt_clear_sectors (disk->dev,
PED_LE64_TO_CPU (primary_gpt->AlternateLBA), 1);
- gpt_disk_data->AlternateLBA = gpt_disk_end;
+ gpt_disk_data->AlternateLBA = disk->dev->length -1;
write_back = 1;
}
}
--
1.9.0