diff --git a/.cvsignore b/.cvsignore index 9710930..37dc0fe 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -gdisk-0.6.3.tgz +gdisk-0.6.5.tgz diff --git a/gdisk-0.6.5-alignment.patch b/gdisk-0.6.5-alignment.patch new file mode 100644 index 0000000..a4c3300 --- /dev/null +++ b/gdisk-0.6.5-alignment.patch @@ -0,0 +1,404 @@ +From: srs5694 +Date: Fri, 19 Mar 2010 18:21:59 +0000 (-0400) +Subject: Changes to sector alignment policies and behavior when restoring a +X-Git-Url: http://gptfdisk.git.sourceforge.net/git/gitweb.cgi?p=gptfdisk%2Fgptfdisk;a=commitdiff_plain;h=a8582cfe6c1aa5e5f80458ac72d881a04ae0ba44;hp=55d926192adc984462509b2966e23bc0d1129bbd + +Changes to sector alignment policies and behavior when restoring a +backup fails +--- + +diff --git a/CHANGELOG b/CHANGELOG +index 2d7b600..a887aa9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,22 @@ ++0.6.6 (?/?/2010): ++----------------- ++ ++- More alignment changes: GPT fdisk now attempts to determine the ++ alignment value based on alignment of current partitions, if any are ++ defined. If no partitions are defined, a default value of 2048 is ++ set. If the computed value is less than 8 on drives over about 596GiB, ++ it's reset to 8, since the drive might be a WD Advanced Format unit ++ that requires an 8-sector (or larger power-of-2) alignment value ++ for proper functioning. The 2048-sector default provides better ++ alignment in some RAID configurations. ++ ++- Changed behavior when a backup restore fails. Previously, GPT fdisk ++ would create a fresh blank set of partitions. Now it does so only ++ if the failure occurs when interpreting the backup's contents; if the ++ user typed the wrong filename, the in-memory data structures aren't ++ touched. ++ ++ + 0.6.5 (3/7/2010): + ----------------- + +diff --git a/attributes.cc b/attributes.cc +index ac9f1fc..f210522 100644 +--- a/attributes.cc ++++ b/attributes.cc +@@ -73,7 +73,7 @@ void Attributes::ChangeAttributes(void) { + do { + response = GetNumber(0, 64, -1, (string) "Toggle which attribute field (0-63, 64 to exit): "); + if (response != 64) { +- bitValue = PowerOf2(NUM_ATR - response - 1); // Find the integer value of the bit ++ bitValue = PowerOf2(uint32_t (NUM_ATR - response - 1)); // Find the integer value of the bit + if ((bitValue & attributes) == bitValue) { // bit is set + attributes -= bitValue; // so unset it + cout << "Have disabled the '" << atNames[response] << "' attribute.\n"; +diff --git a/diskio.cc b/diskio.cc +index a276b5d..d9004f7 100644 +--- a/diskio.cc ++++ b/diskio.cc +@@ -34,6 +34,7 @@ + + #include "support.h" + #include "diskio.h" ++#include "gpt.h" + + using namespace std; + +@@ -93,11 +94,12 @@ int DiskIO::OpenForWrite(const string & filename) { + // returns 1-sector alignment for unusual sector sizes and drives smaller than + // a size defined by SMALLEST_ADVANCED_FORMAT, and 8-sector alignment for + // larger drives with 512-byte sectors. +-int DiskIO::FindAlignment(void) { +- int err, result; ++uint32_t DiskIO::FindAlignment(void) { ++ int err; ++ uint32_t result; + + if ((GetBlockSize() == 512) && (DiskSize(&err) >= SMALLEST_ADVANCED_FORMAT)) { +- result = 8; // play it safe; align for 4096-byte sectors ++ result = DEFAULT_ALIGNMENT; // play it safe; align for 4096-byte sectors + } else { + result = 1; // unusual sector size; assume it's the real physical size + } // if/else +diff --git a/diskio.h b/diskio.h +index 75512c1..516adbf 100644 +--- a/diskio.h ++++ b/diskio.h +@@ -35,10 +35,6 @@ + + using namespace std; + +-// Below constant corresponds to an 800GB disk -- a somewhat arbitrary +-// cutoff +-#define SMALLEST_ADVANCED_FORMAT UINT64_C(1677721600) +- + /*************************************** + * * + * DiskIO class and related structures * +@@ -71,7 +67,7 @@ class DiskIO { + int Write(void* buffer, int numBytes); + void DiskSync(void); // resync disk caches to use new partitions + int GetBlockSize(void); +- int FindAlignment(void); ++ uint32_t FindAlignment(void); + int FindAlignment(const string & filename); + int IsOpen(void) {return isOpen;} + int IsOpenForWrite(void) {return openForWrite;} +diff --git a/gdisk.8 b/gdisk.8 +index 037bd0d..ea4fcaf 100644 +--- a/gdisk.8 ++++ b/gdisk.8 +@@ -458,7 +458,7 @@ important filesystem data structures can span physical sectors on the disk. + To minimize such problems, GPT fdisk aligns the start of partitions on the + boundary of presumed physical sectors. You can set the number of logical + sectors per physical sector with this option. The default is 1 on disks +-smaller than 800GB and 8 on larger disks. ++smaller than 596 GiB and 8 on larger disks with 512\-byte logical sectors. + + .TP + .B m +diff --git a/gdisk.cc b/gdisk.cc +index fc0355c..a3e4bb9 100644 +--- a/gdisk.cc ++++ b/gdisk.cc +@@ -318,6 +318,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) { + uint32_t pn, temp1, temp2; + int goOn = 1; + GUIDData aGUID; ++ ostringstream prompt; + + do { + cout << "\nExpert command (? for help): "; +@@ -355,8 +356,10 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) { + theGPT->ShowDetails(); + break; + case 'l': case 'L': +- temp1 = GetNumber(1, 128, 8, (string) +- "Enter the sector alignment value (1-128, default = 8): "); ++ prompt.seekp(0); ++ prompt << "Enter the sector alignment value (1-" << MAX_ALIGNMENT << ", default = " ++ << DEFAULT_ALIGNMENT << "): "; ++ temp1 = GetNumber(1, MAX_ALIGNMENT, DEFAULT_ALIGNMENT, prompt.str()); + theGPT->SetAlignment(temp1); + break; + case 'm': case 'M': +diff --git a/gpt.cc b/gpt.cc +index ac42995..a407d37 100644 +--- a/gpt.cc ++++ b/gpt.cc +@@ -14,6 +14,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -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 * +diff --git a/gpt.h b/gpt.h +index b2657e7..e353ce0 100644 +--- a/gpt.h ++++ b/gpt.h +@@ -16,7 +16,7 @@ + #ifndef __GPTSTRUCTS + #define __GPTSTRUCTS + +-#define GPTFDISK_VERSION "0.6.5" ++#define GPTFDISK_VERSION "0.6.6-pre1" + + // Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest- + // numbered value to refer to partition numbers. (Most will be 0 or positive, +@@ -24,6 +24,16 @@ + #define MBR_EFI_GPT -1 + #define MBR_EMPTY -2 + ++// Default values for sector alignment ++#define DEFAULT_ALIGNMENT 2048 ++#define MAX_ALIGNMENT 32768 ++ ++// Below constant corresponds to an 800GB disk -- a somewhat arbitrary ++// cutoff ++//#define SMALLEST_ADVANCED_FORMAT UINT64_C(1677721600) ++// Now ~596GiB (640MB), since WD has introduced a smaller Advanced Format drive ++#define SMALLEST_ADVANCED_FORMAT UINT64_C(1250263728) ++ + using namespace std; + + class PartNotes; +@@ -79,7 +89,7 @@ protected: + int secondPartsCrcOk; + int apmFound; // set to 1 if APM detected + int bsdFound; // set to 1 if BSD disklabel detected in MBR +- int sectorAlignment; // Start & end partitions at multiples of sectorAlignment ++ uint32_t sectorAlignment; // Start & end partitions at multiples of sectorAlignment + int beQuiet; + WhichToUse whichWasUsed; + +@@ -177,8 +187,9 @@ public: + int IsFreePartNum(uint32_t partNum); + + // Change how functions work, or return information on same +- void SetAlignment(int n) {sectorAlignment = n;} +- int GetAlignment(void) {return sectorAlignment;} ++ void SetAlignment(uint32_t n); ++ uint32_t ComputeAlignment(void); // Set alignment based on current partitions ++ uint32_t GetAlignment(void) {return sectorAlignment;} + void JustLooking(int i = 1) {justLooking = i;} + void BeQuiet(int i = 1) {beQuiet = i;} + WhichToUse WhichWasUsed(void) {return whichWasUsed;} +diff --git a/mbr.cc b/mbr.cc +index b142a7a..249fc27 100644 +--- a/mbr.cc ++++ b/mbr.cc +@@ -85,7 +85,7 @@ int MBRData::ReadMBRData(const string & deviceFilename) { + canDeleteMyDisk = 1; + } // if + if (myDisk->OpenForRead(deviceFilename)) { +- ReadMBRData(myDisk); ++ allOK = ReadMBRData(myDisk); + } else { + allOK = 0; + } // if +@@ -101,7 +101,7 @@ int MBRData::ReadMBRData(const string & deviceFilename) { + // Note that any extended partition(s) present will be explicitly stored + // in the partitions[] array, along with their contained partitions; the + // extended container partition(s) should be ignored by other functions. +-void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) { ++int MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) { + int allOK = 1, i, j, logicalNum; + int err = 1; + TempMBR tempMBR; +@@ -201,6 +201,7 @@ void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) { + } // for + } // if (hybrid detection code) + } // no initial error ++ return allOK; + } // MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) + + // This is a recursive function to read all the logical partitions, following the +diff --git a/mbr.h b/mbr.h +index 1e838a6..026aeec 100644 +--- a/mbr.h ++++ b/mbr.h +@@ -89,7 +89,7 @@ public: + + // File I/O functions... + int ReadMBRData(const string & deviceFilename); +- void ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1); ++ int ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1); + // ReadLogicalPart() returns last partition # read to logicals[] array, + // or -1 if there was a problem.... + int ReadLogicalPart(uint32_t extendedStart, uint32_t diskOffset, +diff --git a/sgdisk.8 b/sgdisk.8 +index 64516da..45885cc 100644 +--- a/sgdisk.8 ++++ b/sgdisk.8 +@@ -149,10 +149,10 @@ sibling. Options available in \fBsgdisk\fR are: + .B \-a, \-\-set\-alignment=value + Set the sector alignment multiple. GPT fdisk aligns the start of partitions + to sectors that are multiples of this value, which defaults to 8 on disks +-larger than 800GiB with 512\-byte sectors and to 1 on smaller disks or those +-with non\-512\-byte sectors. This alignment value is necessary to obtain +-optimum performance with Western Digital Advanced Format and similar drives +-with larger physical than logical sector sizes. ++larger than 596 GiB with 512\-byte logical sectors and to 1 on smaller ++disks or those with non\-512\-byte sectors. This alignment value is ++necessary to obtain optimum performance with Western Digital Advanced ++Format and similar drives with larger physical than logical sector sizes. + + .TP + .B \-b, \-\-backup=file +diff --git a/sgdisk.cc b/sgdisk.cc +index 911f0c2..2797025 100644 +--- a/sgdisk.cc ++++ b/sgdisk.cc +@@ -33,7 +33,7 @@ int main(int argc, char *argv[]) { + GPTData theGPT; + int opt, numOptions = 0, saveData = 0, neverSaveData = 0; + int partNum = 0, deletePartNum = 0, infoPartNum = 0, bsdPartNum = 0, saveNonGPT = 1; +- int alignment = 8, retval = 0, pretend = 0; ++ int alignment = DEFAULT_ALIGNMENT, retval = 0, pretend = 0; + unsigned int hexCode; + uint32_t tableSize = 128; + uint64_t startSector, endSector; +diff --git a/support.cc b/support.cc +index ab8f767..11c6200 100644 +--- a/support.cc ++++ b/support.cc +@@ -246,11 +246,11 @@ void ReverseBytes(void* theValue, int numBytes) { + + // Compute (2 ^ value). Given the return type, value must be 63 or less. + // Used in some bit-fiddling functions +-uint64_t PowerOf2(int value) { ++uint64_t PowerOf2(uint32_t value) { + uint64_t retval = 1; +- int i; ++ uint32_t i; + +- if ((value < 64) && (value >= 0)) { ++ if (value < 64) { + for (i = 0; i < value; i++) { + retval *= 2; + } // for +diff --git a/support.h b/support.h +index de9b798..8e29f7a 100644 +--- a/support.h ++++ b/support.h +@@ -55,6 +55,6 @@ string BytesToSI(uint64_t size); + unsigned char StrToHex(const string & input, unsigned int position); + int IsLittleEndian(void); // Returns 1 if CPU is little-endian, 0 if it's big-endian + void ReverseBytes(void* theValue, int numBytes); // Reverses byte-order of theValue +-uint64_t PowerOf2(int value); ++uint64_t PowerOf2(uint32_t value); + + #endif diff --git a/gdisk.spec b/gdisk.spec index bb363c2..d82c621 100644 --- a/gdisk.spec +++ b/gdisk.spec @@ -1,11 +1,13 @@ Summary: An fdisk-like partitioning tool for GPT disks Name: gdisk -Version: 0.6.3 -Release: 2%{?dist} +Version: 0.6.5 +Release: 1%{?dist} License: GPLv2 URL: http://www.rodsbooks.com/gdisk/ Group: System Environment/Base Source0: http://downloads.sourceforge.net/gptfdisk/gdisk-%{version}.tgz +# patch from upstream +Patch0: gdisk-0.6.5-alignment.patch BuildRequires: popt-devel libuuid-devel BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) %description @@ -16,6 +18,7 @@ tables, and the ability to convert MBR disks to GPT format. %prep %setup -q +%patch0 -p1 %build %{__make} CXXFLAGS="%{optflags}" @@ -39,16 +42,20 @@ tables, and the ability to convert MBR disks to GPT format. %{_mandir}/man8/sgdisk.8* %changelog -* Thu Mar 11 2010 Terje Rosten - 0.6.3-2 +* Sat Mar 20 2010 Terje Rosten - 0.6.5-1 +- 0.6.5 +- Add alignment patch (bz #575297) + +* Thu Mar 11 2010 Terje Rosten - 0.6.3-2 - Fix source url -* Sun Feb 14 2010 Terje Rosten - 0.6.3-1 +* Sun Feb 14 2010 Terje Rosten - 0.6.3-1 - 0.6.3 -* Sun Jan 31 2010 Terje Rosten - 0.6.2-1 +* Sun Jan 31 2010 Terje Rosten - 0.6.2-1 - 0.6.2 -* Mon Jan 25 2010 Terje Rosten - 0.6.1-1 +* Mon Jan 25 2010 Terje Rosten - 0.6.1-1 - 0.6.1 - add popt-devel to buildreq - random clean up diff --git a/sources b/sources index 2febcee..827ab89 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -0a43faf9c990fdf45d371dc623830e11 gdisk-0.6.3.tgz +75110b32e1ed27b0fcac6f0d89feae57 gdisk-0.6.5.tgz