summaryrefslogtreecommitdiff
path: root/gpt.cc
diff options
context:
space:
mode:
authorsrs5694 <srs5694@users.sourceforge.net>2010-10-07 13:00:45 -0400
committersrs5694 <srs5694@users.sourceforge.net>2010-10-07 13:00:45 -0400
commit0873e9d0e9345a2c4418b4718db525c9f1111c83 (patch)
tree4c6b2adf5d20e0bce392eb2cf0ebc47801d9495b /gpt.cc
parentab4b0438394df4ae6bdea86194e254d7d35fdea0 (diff)
downloadsgdisk-0873e9d0e9345a2c4418b4718db525c9f1111c83.tar.gz
Version 0.6.12 release; mostly changes in support for disks with other
than 512-byte sectors.
Diffstat (limited to 'gpt.cc')
-rw-r--r--gpt.cc76
1 files changed, 39 insertions, 37 deletions
diff --git a/gpt.cc b/gpt.cc
index be3373d..3c9b843 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -58,7 +58,7 @@ GPTData::GPTData(void) {
secondPartsCrcOk = 0;
apmFound = 0;
bsdFound = 0;
- sectorAlignment = 8; // Align partitions on 4096-byte boundaries by default
+ sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default
beQuiet = 0;
whichWasUsed = use_new;
srand((unsigned int) time(NULL));
@@ -81,7 +81,7 @@ GPTData::GPTData(string filename) {
secondPartsCrcOk = 0;
apmFound = 0;
bsdFound = 0;
- sectorAlignment = 8; // Align partitions on 4096-byte boundaries by default
+ sectorAlignment = MIN_AF_ALIGNMENT; // Align partitions on 4096-byte boundaries by default
beQuiet = 0;
whichWasUsed = use_new;
srand((unsigned int) time(NULL));
@@ -248,9 +248,9 @@ int GPTData::Verify(void) {
if (problems == 0) {
totalFree = FindFreeBlocks(&numSegments, &largestSegment);
cout << "No problems found. " << totalFree << " free sectors ("
- << BytesToSI(totalFree * (uint64_t) blockSize) << ") available in "
+ << BytesToSI(totalFree, blockSize) << ") available in "
<< numSegments << "\nsegments, the largest of which is "
- << largestSegment << " (" << BytesToSI(largestSegment * (uint64_t) blockSize)
+ << largestSegment << " (" << BytesToSI(largestSegment, blockSize)
<< ") in size.\n";
} else {
cout << "\nIdentified " << problems << " problems!\n";
@@ -551,7 +551,7 @@ int GPTData::FindInsanePartitions(void) {
} // if
if (partitions[i].GetLastLBA() >= diskSize) {
problems++;
- cout << "\nProblem: partition " << i + 1<< " is too big for the disk.\n";
+ cout << "\nProblem: partition " << i + 1 << " is too big for the disk.\n";
} // if
} // for
return problems;
@@ -876,11 +876,10 @@ int GPTData::SaveGPTData(int quiet, string filename) {
int allOK = 1, littleEndian;
char answer;
- if (filename == "")
- filename = device;
-
littleEndian = IsLittleEndian();
+ if (filename == "")
+ filename = device;
if (filename == "") {
cerr << "Device not defined.\n";
} // if
@@ -1113,16 +1112,12 @@ int GPTData::LoadGPTBackup(const string & filename) {
if ((val = CheckHeaderValidity()) > 0) {
if (val == 2) { // only backup header seems to be good
SetGPTSize(secondHeader.numParts);
-// numParts = secondHeader.numParts;
sizeOfEntries = secondHeader.sizeOfPartitionEntries;
} else { // main header is OK
SetGPTSize(mainHeader.numParts);
-// numParts = mainHeader.numParts;
sizeOfEntries = mainHeader.sizeOfPartitionEntries;
} // if/else
-// SetGPTSize(numParts);
-
if (secondHeader.currentLBA != diskSize - UINT64_C(1)) {
cout << "Warning! Current disk size doesn't match that of the backup!\n"
<< "Adjusting sizes to match, but subsequent problems are possible!\n";
@@ -1266,7 +1261,7 @@ void GPTData::DisplayGPTData(void) {
uint64_t temp, totalFree;
cout << "Disk " << device << ": " << diskSize << " sectors, "
- << BytesToSI(diskSize * blockSize) << "\n";
+ << BytesToSI(diskSize, blockSize) << "\n";
cout << "Logical sector size: " << blockSize << " bytes\n";
cout << "Disk identifier (GUID): " << mainHeader.diskGUID << "\n";
cout << "Partition table holds up to " << numParts << " entries\n";
@@ -1275,7 +1270,7 @@ void GPTData::DisplayGPTData(void) {
totalFree = FindFreeBlocks(&i, &temp);
cout << "Partitions will be aligned on " << sectorAlignment << "-sector boundaries\n";
cout << "Total free space is " << totalFree << " sectors ("
- << BytesToSI(totalFree * (uint64_t) blockSize) << ")\n";
+ << BytesToSI(totalFree, blockSize) << ")\n";
cout << "\nNumber Start (sector) End (sector) Size Code Name\n";
for (i = 0; i < numParts; i++) {
partitions[i].ShowSummary(i, blockSize);
@@ -1284,7 +1279,7 @@ void GPTData::DisplayGPTData(void) {
// Show detailed information on the specified partition
void GPTData::ShowPartDetails(uint32_t partNum) {
- if (partitions[partNum].GetFirstLBA() != 0) {
+ if (!IsFreePartNum(partNum)) {
partitions[partNum].ShowDetails(blockSize);
} else {
cout << "Partition #" << partNum + 1 << " does not exist.";
@@ -1780,7 +1775,10 @@ int GPTData::ClearGPTData(void) {
for (i = 0; i < GPT_RESERVED; i++) {
mainHeader.reserved2[i] = '\0';
} // for
- sectorAlignment = DEFAULT_ALIGNMENT;
+ if (blockSize > 0)
+ sectorAlignment = DEFAULT_ALIGNMENT * SECTOR_SIZE / blockSize;
+ else
+ sectorAlignment = DEFAULT_ALIGNMENT;
// Now some semi-static items (computed based on end of disk)
mainHeader.backupLBA = diskSize - UINT64_C(1);
@@ -2174,31 +2172,37 @@ int GPTData::IsFreePartNum(uint32_t partNum) {
// Set partition alignment value; partitions will begin on multiples of
// the specified value
void GPTData::SetAlignment(uint32_t n) {
- sectorAlignment = n;
+ if (n > 0)
+ sectorAlignment = n;
+ else
+ cerr << "Attempt to set partition alignment to 0!\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 or equal to the DEFAULT_ALIGNMENT value, but not by the
-// previously-located alignment value, 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
+// value less than or equal to the DEFAULT_ALIGNMENT value (adjusted for the
+// sector size), but not by the previously-located alignment value, 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) (or an
+// adjustment of that based on the current sector size). 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).
+// is used on big 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;
uint32_t align = DEFAULT_ALIGNMENT;
- exponent = (uint32_t) log2(DEFAULT_ALIGNMENT);
+ if (blockSize > 0)
+ align = DEFAULT_ALIGNMENT * SECTOR_SIZE / blockSize;
+ exponent = (uint32_t) log2(align);
for (i = 0; i < numParts; i++) {
if (partitions[i].IsUsed()) {
found = 0;
while (!found) {
- align = UINT64_C(1)<<exponent;
+ align = UINT64_C(1) << exponent;
if ((partitions[i].GetFirstLBA() % align) == 0) {
found = 1;
} else {
@@ -2207,9 +2211,9 @@ uint32_t GPTData::ComputeAlignment(void) {
} // while
} // if
} // for
- if ((align < 8) && (diskSize >= SMALLEST_ADVANCED_FORMAT))
- align = 8;
- SetAlignment(align);
+ if ((align < MIN_AF_ALIGNMENT) && (diskSize >= SMALLEST_ADVANCED_FORMAT))
+ align = MIN_AF_ALIGNMENT;
+ sectorAlignment = align;
return align;
} // GPTData::ComputeAlignment()
@@ -2296,14 +2300,12 @@ int GPTData::ManageAttributes(int partNum, const string & command, const string
// Show all attributes for a specified partition....
void GPTData::ShowAttributes(const uint32_t partNum) {
- Attributes theAttr (partitions[partNum].GetAttributes());
- theAttr.ShowAttributes(partNum);
+ partitions[partNum].ShowAttributes(partNum);
} // GPTData::ShowAttributes
// Show whether a single attribute bit is set (terse output)...
void GPTData::GetAttribute(const uint32_t partNum, const string& attributeBits) {
- Attributes theAttr (partitions[partNum].GetAttributes());
- theAttr.OperateOnAttributes(partNum, "get", attributeBits);
+ partitions[partNum].GetAttributes().OperateOnAttributes(partNum, "get", attributeBits);
} // GPTData::GetAttribute
@@ -2361,10 +2363,10 @@ int SizesOK(void) {
allOK = 0;
} // if
// Determine endianness; warn user if running on big-endian (PowerPC, etc.) hardware
- if (IsLittleEndian() == 0) {
- cerr << "\aRunning on big-endian hardware. Big-endian support is new and poorly"
- " tested!\n";
- } // if
+// if (IsLittleEndian() == 0) {
+// cerr << "\aRunning on big-endian hardware. Big-endian support is new and poorly"
+// " tested!\n";
+// } // if
return (allOK);
} // SizesOK()