Changes to sector alignment policies and behavior when restoring a

backup fails
This commit is contained in:
srs5694
2010-03-19 14:21:59 -04:00
parent 55d926192a
commit a8582cfe6c
14 changed files with 122 additions and 34 deletions

68
gpt.cc
View File

@@ -14,6 +14,7 @@
#include <stdint.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <sys/stat.h>
#include <errno.h>
@@ -641,6 +642,7 @@ int GPTData::LoadPartitions(const string & deviceFilename) {
if (allOK)
CheckGPTSize();
myDisk.Close();
ComputeAlignment();
} else {
allOK = 0;
} // if/else
@@ -1116,20 +1118,20 @@ int GPTData::LoadGPTBackup(const string & filename) {
if (!LoadPartitionTable(mainHeader, backupFile, (uint64_t) (3 - shortBackup)))
cerr << "Warning! Read error " << errno
<< " loading partition table; strange behavior now likely!\n";
} else {
allOK = 0;
} // if/else
// Something went badly wrong, so blank out partitions
if (allOK == 0) {
cerr << "Improper backup file! Clearing all partition data!\n";
ClearGPTData();
protectiveMBR.MakeProtectiveMBR();
} // if
} else {
allOK = 0;
cerr << "Unable to open file " << filename << " for reading! Aborting!\n";
} // if/else
// Something went badly wrong, so blank out partitions
if (allOK == 0) {
ClearGPTData();
protectiveMBR.MakeProtectiveMBR();
} // if
return allOK;
} // GPTData::LoadGPTBackup()
@@ -2123,6 +2125,60 @@ int GPTData::IsFreePartNum(uint32_t partNum) {
return retval;
} // GPTData::IsFreePartNum()
/***********************************************************
* *
* Change how functions work or return information on them *
* *
***********************************************************/
// Set partition alignment value; partitions will begin on multiples of
// the specified value
void GPTData::SetAlignment(uint32_t n) {
uint32_t l2;
sectorAlignment = n;
l2 = (uint32_t) log2(n);
if (PowerOf2(l2) != n)
cout << "Information: Your alignment value is not a power of 2.\n";
} // GPTData::SetAlignment()
// Compute sector alignment based on the current partitions (if any). Each
// partition's starting LBA is examined, and if it's divisible by a power-of-2
// value less than the maximum found so far (or 2^31 for the first partition
// found), then the alignment value is adjusted down. If the computed
// alignment is less than 8 and the disk is bigger than SMALLEST_ADVANCED_FORMAT,
// resets it to 8. This is a safety measure for WD Advanced Format and
// similar drives. If no partitions are defined, the alignment value is set
// to DEFAULT_ALIGNMENT (2048). The result is that new drives are aligned to
// 2048-sector multiples but the program won't complain about other alignments
// on existing disks unless a smaller-than-8 alignment is used on small disks
// (as safety for WD Advanced Format drives).
// Returns the computed alignment value.
uint32_t GPTData::ComputeAlignment(void) {
uint32_t i = 0, found, exponent = 31;
uint64_t align = DEFAULT_ALIGNMENT;
for (i = 0; i < mainHeader.numParts; i++) {
if (partitions[i].IsUsed()) {
found = 0;
while (!found) {
align = PowerOf2(exponent);
if ((partitions[i].GetFirstLBA() % align) == 0) {
found = 1;
} else {
exponent--;
} // if/else
} // while
} // if
} // for
if ((align < 8) && (diskSize >= SMALLEST_ADVANCED_FORMAT))
align = 8;
// cout << "Setting alignment to " << align << "\n";
SetAlignment(align);
return align;
} // GPTData::ComputeAlignment()
/********************************
* *
* Endianness support functions *