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:
parent
174308d9b1
commit
e4c0070fe6
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)) {
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user