Bring git up to 0.6.6 release version.

This commit is contained in:
srs5694
2010-03-21 19:05:49 -04:00
parent a8582cfe6c
commit 8a4ddfc919
11 changed files with 96 additions and 156 deletions

View File

@@ -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

View File

@@ -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";

View File

@@ -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

View File

@@ -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)

View File

@@ -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;}

44
gdisk.8
View File

@@ -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 *

63
gpt.cc
View File

@@ -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()

4
gpt.h
View File

@@ -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

2
mbr.cc
View File

@@ -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

View File

@@ -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

View File

@@ -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);