summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsrs5694 <srs5694@users.sourceforge.net>2010-03-21 19:05:49 -0400
committersrs5694 <srs5694@users.sourceforge.net>2010-03-21 19:05:49 -0400
commit8a4ddfc919d5569c68489cf53d9cf5abc94c410c (patch)
tree7ed961f3d10386b896570c185ec3b21d3b4a53ab
parenta8582cfe6c1aa5e5f80458ac72d881a04ae0ba44 (diff)
downloadsgdisk-8a4ddfc919d5569c68489cf53d9cf5abc94c410c.tar.gz
Bring git up to 0.6.6 release version.
-rw-r--r--CHANGELOG37
-rw-r--r--attributes.cc2
-rw-r--r--current.spec10
-rw-r--r--diskio.cc72
-rw-r--r--diskio.h2
-rw-r--r--gdisk.844
-rw-r--r--gpt.cc63
-rw-r--r--gpt.h4
-rw-r--r--mbr.cc2
-rw-r--r--sgdisk.813
-rw-r--r--sgdisk.cc3
11 files changed, 96 insertions, 156 deletions
diff --git a/CHANGELOG b/CHANGELOG
index a887aa9..fe1da76 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,14 +1,33 @@
-0.6.6 (?/?/2010):
+0.6.6 (3/21/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.
+- Added support for the "no block IO protocol" (referred to as "hide from
+ EFI" in GPT fdisk) and "legacy BIOS bootable" attribute bits. See Table
+ 19 of the UEFI 2.3 specification (p. 153) for details.
+
+- Changed the sequence in which GPT data structures are written to disk;
+ backups are now written first, followed by the main structures. This is
+ as recommended in the UEFI 2.3 specification, since it's safer in the
+ extremely unlikely event that a RAID array's size is increased and
+ there's a power outage mid-write. (If the main structures are written
+ first in this case, they'll point to data that's not yet been written;
+ but by writing the backups first, the old main structures will still
+ point to the valid old backup structures.)
+
+- Protective MBRs now have disk signatures of 0x00000000, to better
+ conform with GPT as described in the UEFI 2.3 specification.
+
+- Added alignment information to the summary data produced by the
+ 'p' main-menu option in gdisk or the -p option to sgdisk.
+
+- 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 best performance. 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
diff --git a/attributes.cc b/attributes.cc
index f210522..527dc87 100644
--- a/attributes.cc
+++ b/attributes.cc
@@ -32,6 +32,8 @@ Attributes::Attributes(void) {
// Now reset those names that are defined....
atNames[0] = "system partition"; // required for computer to operate
+ atNames[1] = "hide from EFI";
+ atNames[2] = "legacy BIOS bootable";
atNames[60] = "read-only";
atNames[62] = "hidden";
atNames[63] = "do not automount";
diff --git a/current.spec b/current.spec
index 4eeedde..f610336 100644
--- a/current.spec
+++ b/current.spec
@@ -1,11 +1,11 @@
Summary: An fdisk-like partitioning tool for GPT disks
Name: gdisk
-Version: 0.6.5
+Version: 0.6.6
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
Group: Applications/System
-Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.5.tgz
+Source: http://www.rodsbooks.com/gdisk/gdisk-0.6.6.tgz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description
@@ -19,7 +19,7 @@ and the ability to convert MBR disks to GPT format.
%setup -q
%build
-make CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_CXX_FLAGS"
+make CFLAGS="$RPM_OPT_FLAGS" CXXFLAGS="$RPM_OPT_CXX_FLAGS -D_FILE_OFFSET_BITS=64 -O2"
%install
rm -rf $RPM_BUILD_ROOT
@@ -40,5 +40,5 @@ rm -rf $RPM_BUILD_ROOT
%doc %{_mandir}/man8*
%changelog
-* Sun Mar 7 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.5
-- Created spec file for 0.6.5 release
+* Sun Mar 21 2010 R Smith <rodsmith@rodsbooks.com> - 0.6.6
+- Created spec file for 0.6.6 release
diff --git a/diskio.cc b/diskio.cc
index d9004f7..d433d3d 100644
--- a/diskio.cc
+++ b/diskio.cc
@@ -87,75 +87,3 @@ int DiskIO::OpenForWrite(const string & filename) {
} // if/else
return retval;
} // DiskIO::OpenForWrite(string filename)
-
-// My original FindAlignment() function (after this one) isn't working, since
-// the BLKPBSZGET ioctl() isn't doing what I expected (it returns 512 even on
-// a WD Advanced Format drive). Therefore, I'm using a simpler function that
-// 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.
-uint32_t DiskIO::FindAlignment(void) {
- int err;
- uint32_t result;
-
- if ((GetBlockSize() == 512) && (DiskSize(&err) >= SMALLEST_ADVANCED_FORMAT)) {
- 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
- return result;
-} // DiskIO::FindAlignment
-
-// Return the partition alignment value in sectors. Right now this works
-// only for Linux 2.6.32 and later, since I can't find equivalent ioctl()s
-// for OS X or FreeBSD, and the Linux ioctl is new
-/* int DiskIO::FindAlignment(int fd) {
- int err = -2, errnum = 0, result = 8, physicalSectorSize = 4096;
- uint64_t diskSize;
-
-#if defined (__linux__) && defined (BLKPBSZGET)
- err = ioctl(fd, BLKPBSZGET, &physicalSectorSize);
- cout << "In FindAlignment(), physicalSectorSize = " << physicalSectorSize
- << ", err = " << err << "\n";
-#else
- err = -1;
-#endif
-
- if (err < 0) { // ioctl didn't work; have to guess....
- if (GetBlockSize(fd) == 512) {
- result = 8; // play it safe; align for 4096-byte sectors
-} else {
- result = 1; // unusual sector size; assume it's the real physical size
-} // if/else
-} else { // ioctl worked; compute alignment
- result = physicalSectorSize / GetBlockSize(fd);
- // Disks with larger physical than logical sectors must theoretically
- // have a total disk size that's a multiple of the physical sector
- // size; however, some such disks have compatibility jumper settings
- // meant for one-partition MBR setups, and these reduce the total
- // number of sectors by 1. If such a setting is used, it'll result
- // in improper alignment, so look for this condition and warn the
- // user if it's found....
- diskSize = disksize(fd, &errnum);
- if ((diskSize % (uint64_t) result) != 0) {
- fprintf(stderr, "\aWarning! Disk size (%I64u) is not a multiple of alignment\n"
- "size (%d), but it should be! Check disk manual and jumper settings!\n",
- (unsigned long long) diskSize, result);
-} // if
-} // if/else
- if (result <= 0) // can happen if physical sector size < logical sector size
- result = 1;
- return result;
-} // DiskIO::FindAlignment(int) */
-
-// The same as FindAlignment(int), but opens and closes a device by filename
-int DiskIO::FindAlignment(const string & filename) {
- int retval = 1;
-
- if (!isOpen)
- OpenForRead(filename);
- if (isOpen) {
- retval = FindAlignment();
- } // if
- return retval;
-} // DiskIO::FindAlignment(char)
diff --git a/diskio.h b/diskio.h
index 516adbf..9c709c5 100644
--- a/diskio.h
+++ b/diskio.h
@@ -67,8 +67,6 @@ class DiskIO {
int Write(void* buffer, int numBytes);
void DiskSync(void); // resync disk caches to use new partitions
int GetBlockSize(void);
- uint32_t FindAlignment(void);
- int FindAlignment(const string & filename);
int IsOpen(void) {return isOpen;}
int IsOpenForWrite(void) {return openForWrite;}
string GetName(void) {return realFilename;}
diff --git a/gdisk.8 b/gdisk.8
index ea4fcaf..ddcec5a 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "GDISK" "8" "0.6.5" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "GDISK" "8" "0.6.6" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
@@ -112,9 +112,9 @@ If Windows is to boot from a GPT disk, a partition of type \fIMicrosoft
Reserved\fR (\fBgdisk\fR
internal code 0x0C01) is recommended. This partition should be about 128 MiB
in size. It ordinarily follows the EFI System Partition and immediately
-precedes the Windows data partitions. (Note that GNU Parted creates all
-FAT partitions as this type, which actually makes the partition unusable
-for normal file storage in both Windows and Mac OS X.)
+precedes the Windows data partitions. (Note that old versions of GNU Parted
+create all FAT partitions as this type, which actually makes the partition
+unusable for normal file storage in both Windows and Mac OS X.)
.TP
.B *
@@ -208,7 +208,8 @@ the end of the same block for the end sector.
.TP
.B o
Clear out all partition data. This includes GPT header data,
-all partition definitions, and the protective MBR.
+all partition definitions, and the protective MBR. The sector alignment
+is reset to the default (2048 sectors, or 1MB).
.TP
.B p
@@ -422,11 +423,8 @@ not in \fBgdisk\fR) or sheer incredible coincidence.
.TP
.B d
-Display the number of logical sectors per physical sector. This value
-determines the sector alignment that GPT fdisk enforces. See the
-description of the 'l' option for more details. Note that this value is
-only auto\-detected on Linux with a 2.6.32 kernel or later; on other
-platforms, it defaults to 8.
+Display the sector alignment value. See the
+description of the 'l' option for more details.
.TP
.B e
@@ -448,17 +446,15 @@ option on the main menu.
.TP
.B l
-Change the number of logical sectors per physical sector. Prior to December
-of 2009, most hard disks used 512\-byte physical sectors. Starting in
-December of 2009, disk manufacturers began transitioning to disks with
-larger physical sectors, but their firmware translated to 512\-byte logical
-sectors to maintain compatibility with older OSes. If partitions begin
-mid\-physical\-sector, though, performance can suffer on such drives, since
-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 596 GiB and 8 on larger disks with 512\-byte logical sectors.
+Change the sector alignment value. Disks with more logical sectors per
+physical sectors (such as some Western Digital models introduced in
+December of 2009) and some RAID configurations can suffer performance
+problems if partitions are not aligned properly for their internal data
+structures. On new disks, GPT fdisk attempts to align partitions on
+2048\-sector (1MiB) boundaries by default, which optimizes performance
+for both of these disk types. On pre\-partitioned disks, GPT fdisk
+attempts to identify the alignment value used on that disk. In either
+case, it can be changed by using this option.
.TP
.B m
@@ -535,14 +531,16 @@ entering data. When only one option is possible, \fBgdisk\fR
usually bypasses the prompt entirely.
.SH "BUGS"
-As of March 2010 (version 0.6.5), \fBgdisk\fR
+As of March 2010 (version 0.6.6), \fBgdisk\fR
should be considered beta software. Known bugs and limitations include:
.TP
.B *
The program compiles correctly only on Linux, FreeBSD, Mac OS X, and Windows.
Linux versions for x86\-64 (64\-bit), x86 (32\-bit), and PowerPC (32\-bit) have been
-tested, with the x86\-64 version having seen the most testing.
+tested, with the x86\-64 version having seen the most testing. Under FreeBSD,
+32\-bit (x86) and 64\-bit (x86\-64) versions have been tested. Only 32\-bit
+versions for Mac OS X and Windows have been tested.
.TP
.B *
diff --git a/gpt.cc b/gpt.cc
index a407d37..9b1faf6 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -608,7 +608,6 @@ int GPTData::LoadPartitions(const string & deviceFilename) {
// store disk information....
diskSize = myDisk.DiskSize(&err);
blockSize = (uint32_t) myDisk.GetBlockSize();
- sectorAlignment = myDisk.FindAlignment();
device = deviceFilename;
PartitionScan(); // Check for partition types, load GPT, & print summary
@@ -928,28 +927,24 @@ int GPTData::SaveGPTData(int quiet) {
// Do it!
if (allOK) {
- // First, write the protective MBR...
- allOK = protectiveMBR.WriteMBRData(&myDisk);
-
- if (allOK && myDisk.OpenForWrite(device)) {
- // Now write the main GPT header...
- allOK = SaveHeader(&mainHeader, myDisk, 1);
-
- // Now write the main partition tables...
- if (allOK) {
- allOK = SavePartitionTable(myDisk, mainHeader.partitionEntriesLBA);
- } // if (allOK)
-
- // Now seek to near the end to write the secondary GPT....
+ if (myDisk.OpenForWrite(device)) {
+ // As per UEFI specs, write the secondary table and GPT first....
allOK = SavePartitionTable(myDisk, secondHeader.partitionEntriesLBA);
if (!allOK)
cerr << "Unable to save backup partition table! Perhaps the 'e' option on the experts'\n"
<< "menu will resolve this problem.\n";
// Now write the secondary GPT header...
- if (allOK) {
- allOK = SaveHeader(&secondHeader, myDisk, mainHeader.backupLBA);
- } // if (allOK)
+ allOK = allOK && SaveHeader(&secondHeader, myDisk, mainHeader.backupLBA);
+
+ // Now write the main partition tables...
+ allOK = allOK && SavePartitionTable(myDisk, mainHeader.partitionEntriesLBA);
+
+ // Now write the main GPT header...
+ allOK = allOK && SaveHeader(&mainHeader, myDisk, 1);
+
+ // To top it off, write the protective MBR...
+ allOK = allOK && protectiveMBR.WriteMBRData(&myDisk);
// re-read the partition table
if (allOK) {
@@ -960,9 +955,9 @@ int GPTData::SaveGPTData(int quiet) {
cout << "The operation has completed successfully.\n";
} else {
cerr << "Warning! An error was reported when writing the partition table! This error\n"
- << "MIGHT be harmless, but you may have trashed the disk! Use parted and, if\n"
- << "necessary, restore your original partition table.\n";
+ << "MIGHT be harmless, but you may have trashed the disk!\n";
} // if/else
+
myDisk.Close();
} else {
cerr << "Unable to open device " << device << " for writing! Errno is "
@@ -1259,6 +1254,7 @@ void GPTData::DisplayGPTData(void) {
cout << "First usable sector is " << mainHeader.firstUsableLBA
<< ", last usable sector is " << mainHeader.lastUsableLBA << "\n";
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";
cout << "\nNumber Start (sector) End (sector) Size Code Name\n";
@@ -1752,6 +1748,7 @@ int GPTData::ClearGPTData(void) {
for (i = 0; i < GPT_RESERVED; i++) {
mainHeader.reserved2[i] = '\0';
} // for
+ sectorAlignment = DEFAULT_ALIGNMENT;
// Now some semi-static items (computed based on end of disk)
mainHeader.backupLBA = diskSize - UINT64_C(1);
@@ -1878,14 +1875,16 @@ int GPTData::Align(uint64_t* sector) {
// Otherwise, notify the user that it couldn't be done....
if (sectorOK == 1) {
cout << "Information: Moved requested sector from " << original << " to "
- << *sector << " for\nalignment purposes.\n";
+ << *sector << " in\norder to align on " << sectorAlignment
+ << "-sector boundaries.\n";
if (!beQuiet)
cout << "Use 'l' on the experts' menu to adjust alignment\n";
} else {
cout << "Information: Sector not aligned on " << sectorAlignment
<< "-sector boundary and could not be moved.\n"
<< "If you're using a Western Digital Advanced Format or similar disk with\n"
- << "underlying 4096-byte sectors, performance may suffer.\n";
+ << "underlying 4096-byte sectors or certain types of RAID array, performance\n"
+ << "may suffer.\n";
retval = 0;
} // if/else
} // if
@@ -2139,26 +2138,25 @@ void GPTData::SetAlignment(uint32_t n) {
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).
+// 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
+// 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;
+ exponent = (uint32_t) log2(DEFAULT_ALIGNMENT);
for (i = 0; i < mainHeader.numParts; i++) {
if (partitions[i].IsUsed()) {
found = 0;
@@ -2174,7 +2172,6 @@ uint32_t GPTData::ComputeAlignment(void) {
} // for
if ((align < 8) && (diskSize >= SMALLEST_ADVANCED_FORMAT))
align = 8;
-// cout << "Setting alignment to " << align << "\n";
SetAlignment(align);
return align;
} // GPTData::ComputeAlignment()
diff --git a/gpt.h b/gpt.h
index e353ce0..cae0339 100644
--- a/gpt.h
+++ b/gpt.h
@@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS
-#define GPTFDISK_VERSION "0.6.6-pre1"
+#define GPTFDISK_VERSION "0.6.6"
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
@@ -26,7 +26,7 @@
// Default values for sector alignment
#define DEFAULT_ALIGNMENT 2048
-#define MAX_ALIGNMENT 32768
+#define MAX_ALIGNMENT 65536
// Below constant corresponds to an 800GB disk -- a somewhat arbitrary
// cutoff
diff --git a/mbr.cc b/mbr.cc
index 249fc27..0b29bbb 100644
--- a/mbr.cc
+++ b/mbr.cc
@@ -588,7 +588,7 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
// Initialize variables
nulls = 0;
MBRSignature = MBR_SIGNATURE;
- diskSignature = (uint32_t) rand();
+ diskSignature = UINT32_C(0);
partitions[0].status = UINT8_C(0); // Flag the protective part. as unbootable
diff --git a/sgdisk.8 b/sgdisk.8
index 45885cc..ea026d2 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2010 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "SGDISK" "8" "0.6.5" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "SGDISK" "8" "0.6.6" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS"
@@ -148,11 +148,10 @@ sibling. Options available in \fBsgdisk\fR are:
.TP
.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 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.
+to sectors that are multiples of this value, which defaults to 2048 on
+freshly formatted disks. This alignment value is necessary to obtain optimum
+performance with Western Digital Advanced Format and similar drives with larger
+physical than logical sector sizes and with some types of RAID arrays.
.TP
.B \-b, \-\-backup=file
@@ -399,7 +398,7 @@ Non\-GPT disk detected and no \fI\-g\fR option
.B 4
An error prevented saving changes
.SH "BUGS"
-As of March 2010 (version 0.6.5), \fBsgdisk\fR
+As of March 2010 (version 0.6.6), \fBsgdisk\fR
should be considered beta software. Known bugs and limitations include:
.TP
diff --git a/sgdisk.cc b/sgdisk.cc
index 2797025..ab6f7b2 100644
--- a/sgdisk.cc
+++ b/sgdisk.cc
@@ -143,8 +143,7 @@ int main(int argc, char *argv[]) {
} else saveData = 1;
break;
case 'D':
- cout << "Partitions created on multiples of " << theGPT.GetAlignment()
- << " sector(s)\n";
+ cout << theGPT.GetAlignment() << "\n";
break;
case 'e':
theGPT.JustLooking(0);