Author: mmlr Date: 2010-02-28 19:10:29 +0100 (Sun, 28 Feb 2010) New Revision: 35664 Changeset: http://dev.haiku-os.org/changeset/35664/haiku Modified: haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.cpp haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.h haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.cpp haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.h Log: Added a bit of logic to possibly fall back to a fixed 512 block MBR in case certain conditions indicate that we might deal with a fixed 512 bytes MBR on a non 512 byte block size medium. One condition is that at least one partition had to be shrunk to fit the available size (which usually happens with larger block sizes). We retry with a fixed 512 block size once and compare the result if it didn't improve the situation it is reverted again. This is mostly a preparation for the upcoming "anyboot" hybrid MBR/ISO images. Modified: haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.cpp 2010-02-28 18:08:28 UTC (rev 35663) +++ haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.cpp 2010-02-28 18:10:29 UTC (rev 35664) @@ -399,7 +399,7 @@ } -void +bool Partition::FitSizeToSession(off_t sessionSize) { // To work around buggy (or older) BIOS, we shrink the partition size to @@ -408,8 +408,12 @@ // Also, the drive size is obviously reported differently sometimes; this // should let us read problematic drives - let the file system figure out // if something is wrong. - if (sessionSize < fOffset + fSize && sessionSize > fOffset) + if (sessionSize < fOffset + fSize && sessionSize > fOffset) { fSize = sessionSize - fOffset; + return true; + } + + return false; } Modified: haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.h =================================================================== --- haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.h 2010-02-28 18:08:28 UTC (rev 35663) +++ haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMap.h 2010-02-28 18:10:29 UTC (rev 35664) @@ -182,7 +182,7 @@ { fBlockSize = blockSize; } bool CheckLocation(off_t sessionSize) const; - void FitSizeToSession(off_t sessionSize); + bool FitSizeToSession(off_t sessionSize); private: off_t fPartitionTableOffset; Modified: haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.cpp 2010-02-28 18:08:28 UTC (rev 35663) +++ haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.cpp 2010-02-28 18:10:29 UTC (rev 35664) @@ -67,18 +67,45 @@ return B_BAD_VALUE; status_t error; + bool hadToReFitSize = false; fMap = map; fMap->Unset(); if (block) { const partition_table* table = (const partition_table*)block; - error = _ParsePrimary(table); + error = _ParsePrimary(table, hadToReFitSize); } else { partition_table table; error = _ReadPartitionTable(0, &table); - if (error == B_OK) - error = _ParsePrimary(&table); + if (error == B_OK) { + error = _ParsePrimary(&table, hadToReFitSize); + + if (fBlockSize != 512 && (hadToReFitSize + || !fMap->Check(fSessionSize))) { + // This might be a fixed 512 byte MBR on a non-512 medium. + // We do that for the anyboot images for example. so retry + // with a fixed 512 block size and see if we get better + // results + int32 previousPartitionCount = fMap->CountNonEmptyPartitions(); + uint32 previousBlockSize = fBlockSize; + TRACE(("intel: Parse(): trying with a fixed 512 block size\n")); + + fBlockSize = 512; + fMap->Unset(); + error = _ParsePrimary(&table, hadToReFitSize); + + if (fMap->CountNonEmptyPartitions() < previousPartitionCount + || error != B_OK || hadToReFitSize + || !fMap->Check(fSessionSize)) { + // That didn't improve anything, let's revert. + TRACE(("intel: Parse(): try failed, reverting\n")); + fBlockSize = previousBlockSize; + fMap->Unset(); + error = _ParsePrimary(&table, hadToReFitSize); + } + } + } } if (error == B_OK && !fMap->Check(fSessionSize)) @@ -92,7 +119,8 @@ // _ParsePrimary status_t -PartitionMapParser::_ParsePrimary(const partition_table* table) +PartitionMapParser::_ParsePrimary(const partition_table* table, + bool& hadToReFitSize) { if (table == NULL) return B_BAD_VALUE; @@ -104,6 +132,8 @@ return B_BAD_DATA; } + hadToReFitSize = false; + // examine the table for (int32 i = 0; i < 4; i++) { const partition_descriptor* descriptor = &table->table[i]; @@ -111,7 +141,7 @@ partition->SetTo(descriptor, 0, fBlockSize); // work-around potential BIOS/OS problems - partition->FitSizeToSession(fSessionSize); + hadToReFitSize |= partition->FitSizeToSession(fSessionSize); // ignore, if location is bad if (!partition->CheckLocation(fSessionSize)) { Modified: haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.h =================================================================== --- haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.h 2010-02-28 18:08:28 UTC (rev 35663) +++ haiku/trunk/src/add-ons/kernel/partitioning_systems/intel/PartitionMapParser.h 2010-02-28 18:10:29 UTC (rev 35664) @@ -38,7 +38,8 @@ const Partition* PartitionAt(int32 index) const; private: - status_t _ParsePrimary(const partition_table* table); + status_t _ParsePrimary(const partition_table* table, + bool& hadToReFitSize); status_t _ParseExtended(PrimaryPartition* primary, off_t offset); status_t _ReadPartitionTable(off_t offset,