summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsrs5694 <srs5694@users.sourceforge.net>2012-01-21 13:47:24 -0500
committersrs5694 <srs5694@users.sourceforge.net>2012-01-21 13:47:24 -0500
commit706e51217a531c46afc743b556e10fd5c0585fcf (patch)
tree3315fc03511a72788de0240d611bd62dc3b46567
parente69e6807cf84fe2b80c48475531ce4bd09563bba (diff)
downloadsgdisk-706e51217a531c46afc743b556e10fd5c0585fcf.tar.gz
Changes to partition table size management for Solaris-created GPTs
-rw-r--r--NEWS8
-rw-r--r--gpt.cc33
-rw-r--r--gpt.h2
-rw-r--r--gpttext.cc2
-rw-r--r--support.h2
5 files changed, 28 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index 11805ec..e3343fb 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,14 @@
0.8.2 (??/??/2011):
-------------------
+- Adjusted the code to support a number of partitions that's not a multiple
+ of the number of partition table entries that fits in a sector (normally
+ 4 per sector). The program still rounds up, when necessary, when resizing
+ the partition table manually, but not when loading a partition table that
+ contains a peculiar number of partitions. This helps prevent spurious
+ error messages about CRC problems when loading some Solaris partition
+ tables.
+
- Fixed bugs relating to the handling of empty partitions; Solaris's ZFS
tools create weird empty partitions that are legal but that gdisk wasn't
handling properly. (Specifically, they sometimes have non-zero end
diff --git a/gpt.cc b/gpt.cc
index 0281b3f..823f32f 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -317,8 +317,7 @@ int GPTData::CheckGPTSize(void) {
lastUsedBlock = 0;
for (i = 0; i < numParts; i++) {
if (partitions[i].IsUsed()) {
- if ((partitions[i].GetFirstLBA() < firstUsedBlock) &&
- (partitions[i].GetFirstLBA() != 0))
+ if (partitions[i].GetFirstLBA() < firstUsedBlock)
firstUsedBlock = partitions[i].GetFirstLBA();
if (partitions[i].GetLastLBA() > lastUsedBlock) {
lastUsedBlock = partitions[i].GetLastLBA();
@@ -519,7 +518,7 @@ void GPTData::RebuildMainHeader(void) {
mainHeader.partitionEntriesCRC = secondHeader.partitionEntriesCRC;
memcpy(mainHeader.reserved2, secondHeader.reserved2, sizeof(mainHeader.reserved2));
mainCrcOk = secondCrcOk;
- SetGPTSize(mainHeader.numParts);
+ SetGPTSize(mainHeader.numParts, 0);
} // GPTData::RebuildMainHeader()
// Rebuild the secondary GPT header, using the main header as a model.
@@ -540,7 +539,7 @@ void GPTData::RebuildSecondHeader(void) {
secondHeader.partitionEntriesCRC = mainHeader.partitionEntriesCRC;
memcpy(secondHeader.reserved2, mainHeader.reserved2, sizeof(secondHeader.reserved2));
secondCrcOk = mainCrcOk;
- SetGPTSize(secondHeader.numParts);
+ SetGPTSize(secondHeader.numParts, 0);
} // GPTData::RebuildSecondHeader()
// Search for hybrid MBR entries that have no corresponding GPT partition.
@@ -883,7 +882,7 @@ int GPTData::LoadHeader(struct GPTHeader *header, DiskIO & disk, uint64_t sector
*crcOk = CheckHeaderCRC(&tempHeader);
if (allOK && (numParts != tempHeader.numParts) && *crcOk) {
- allOK = SetGPTSize(tempHeader.numParts);
+ allOK = SetGPTSize(tempHeader.numParts, 0);
}
*header = tempHeader;
@@ -906,7 +905,7 @@ int GPTData::LoadPartitionTable(const struct GPTHeader & header, DiskIO & disk,
retval = disk.Seek(sector);
} // if/else
if (retval == 1)
- retval = SetGPTSize(header.numParts);
+ retval = SetGPTSize(header.numParts, 0);
if (retval == 1) {
sizeOfParts = header.numParts * header.sizeOfPartitionEntries;
if (disk.Read(partitions, sizeOfParts) != (int) sizeOfParts) {
@@ -1206,9 +1205,9 @@ int GPTData::LoadGPTBackup(const string & filename) {
// this check!
if ((val = CheckHeaderValidity()) > 0) {
if (val == 2) { // only backup header seems to be good
- SetGPTSize(secondHeader.numParts);
+ SetGPTSize(secondHeader.numParts, 0);
} else { // main header is OK
- SetGPTSize(mainHeader.numParts);
+ SetGPTSize(mainHeader.numParts, 0);
} // if/else
if (secondHeader.currentLBA != diskSize - UINT64_C(1)) {
@@ -1593,19 +1592,21 @@ int GPTData::OnePartToMBR(uint32_t gptPart, int mbrPart) {
**********************************************************************/
// Resizes GPT to specified number of entries. Creates a new table if
-// necessary, copies data if it already exists. Returns 1 if all goes
-// well, 0 if an error is encountered.
-int GPTData::SetGPTSize(uint32_t numEntries) {
+// necessary, copies data if it already exists. If fillGPTSectors is 1
+// (the default), rounds numEntries to fill all the sectors necessary to
+// hold the GPT.
+// Returns 1 if all goes well, 0 if an error is encountered.
+int GPTData::SetGPTSize(uint32_t numEntries, int fillGPTSectors) {
GPTPart* newParts;
- uint32_t i, high, copyNum;
+ uint32_t i, high, copyNum, entriesPerSector;
int allOK = 1;
// First, adjust numEntries upward, if necessary, to get a number
// that fills the allocated sectors
- i = blockSize / GPT_SIZE;
- if ((numEntries % i) != 0) {
+ entriesPerSector = blockSize / GPT_SIZE;
+ if (fillGPTSectors && ((numEntries % entriesPerSector) != 0)) {
cout << "Adjusting GPT size from " << numEntries << " to ";
- numEntries = ((numEntries / i) + 1) * i;
+ numEntries = ((numEntries / entriesPerSector) + 1) * entriesPerSector;
cout << numEntries << " to fill the sector\n";
} // if
@@ -1641,7 +1642,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
partitions = newParts;
} // if/else existing partitions
numParts = numEntries;
- mainHeader.firstUsableLBA = ((numEntries * GPT_SIZE) / blockSize) + 2 ;
+ mainHeader.firstUsableLBA = ((numEntries * GPT_SIZE) / blockSize) + (((numEntries * GPT_SIZE) % blockSize) != 0) + 2 ;
secondHeader.firstUsableLBA = mainHeader.firstUsableLBA;
MoveSecondHeaderToEnd();
if (diskSize > 0)
diff --git a/gpt.h b/gpt.h
index eb2c747..26672d7 100644
--- a/gpt.h
+++ b/gpt.h
@@ -139,7 +139,7 @@ public:
int OnePartToMBR(uint32_t gptPart, int mbrPart); // add one partition to MBR. Returns 1 if successful
// Adjust GPT structures WITHOUT user interaction...
- int SetGPTSize(uint32_t numEntries);
+ int SetGPTSize(uint32_t numEntries, int fillGPTSectors = 1);
void BlankPartitions(void);
int DeletePartition(uint32_t partNum);
uint32_t CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector);
diff --git a/gpttext.cc b/gpttext.cc
index 7ceede5..433332f 100644
--- a/gpttext.cc
+++ b/gpttext.cc
@@ -650,7 +650,7 @@ void GPTDataTextUI::RecoveryMenu(string filename) {
} // if
} else {
MakeProtectiveMBR();
- SetGPTSize(numParts);
+ SetGPTSize(numParts, 0);
cout << "Note: New protective MBR created\n\n";
} // if/else
break;
diff --git a/support.h b/support.h
index 9f927e6..bc3e27d 100644
--- a/support.h
+++ b/support.h
@@ -8,7 +8,7 @@
#ifndef __GPTSUPPORT
#define __GPTSUPPORT
-#define GPTFDISK_VERSION "0.8.1.3"
+#define GPTFDISK_VERSION "0.8.1.4"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64