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.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35664 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz 2010-02-28 18:10:29 +00:00
parent 174308d9b1
commit e4c0070fe6
4 changed files with 44 additions and 9 deletions

View File

@ -399,7 +399,7 @@ Partition::CheckLocation(off_t sessionSize) const
}
void
bool
Partition::FitSizeToSession(off_t sessionSize)
{
// To work around buggy (or older) BIOS, we shrink the partition size to
@ -408,8 +408,12 @@ Partition::FitSizeToSession(off_t sessionSize)
// 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;
}

View File

@ -182,7 +182,7 @@ public:
{ fBlockSize = blockSize; }
bool CheckLocation(off_t sessionSize) const;
void FitSizeToSession(off_t sessionSize);
bool FitSizeToSession(off_t sessionSize);
private:
off_t fPartitionTableOffset;

View File

@ -67,18 +67,45 @@ PartitionMapParser::Parse(const uint8* block, PartitionMap* map)
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 @@ PartitionMapParser::Parse(const uint8* block, PartitionMap* map)
// _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 @@ PartitionMapParser::_ParsePrimary(const partition_table* table)
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 @@ PartitionMapParser::_ParsePrimary(const partition_table* table)
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)) {

View File

@ -38,7 +38,8 @@ public:
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,