* Renamed partition_table_sector to partition_table, and PTS* to
PartitionTable*; the sector is not really a sector, but only the first 512 bytes of it. * Cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30154 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d88bc21991
commit
b41bbb4a46
|
@ -1,13 +1,12 @@
|
|||
/*
|
||||
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold, bonefish@cs.tu-berlin.de
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file PartitionMap.cpp
|
||||
/*! \file PartitionMap.cpp
|
||||
\brief Definitions for "intel" style partitions and implementation
|
||||
of related classes.
|
||||
*/
|
||||
|
@ -292,7 +291,7 @@ PartitionType::FindNext()
|
|||
// constructor
|
||||
Partition::Partition()
|
||||
:
|
||||
fPTSOffset(0),
|
||||
fPartitionTableOffset(0),
|
||||
fOffset(0),
|
||||
fSize(0),
|
||||
fType(0),
|
||||
|
@ -301,21 +300,21 @@ Partition::Partition()
|
|||
}
|
||||
|
||||
// constructor
|
||||
Partition::Partition(const partition_descriptor *descriptor,off_t ptsOffset,
|
||||
Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
|
||||
off_t baseOffset)
|
||||
:
|
||||
fPTSOffset(0),
|
||||
fPartitionTableOffset(0),
|
||||
fOffset(0),
|
||||
fSize(0),
|
||||
fType(0),
|
||||
fActive(false)
|
||||
{
|
||||
SetTo(descriptor, ptsOffset, baseOffset);
|
||||
SetTo(descriptor, tableOffset, baseOffset);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
void
|
||||
Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
|
||||
Partition::SetTo(const partition_descriptor *descriptor, off_t tableOffset,
|
||||
off_t baseOffset)
|
||||
{
|
||||
TRACE(("Partition::SetTo(): active: %x\n", descriptor->active));
|
||||
|
@ -323,16 +322,16 @@ Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
|
|||
(off_t)descriptor->size * SECTOR_SIZE,
|
||||
descriptor->type,
|
||||
descriptor->active,
|
||||
ptsOffset);
|
||||
tableOffset);
|
||||
}
|
||||
|
||||
|
||||
// SetTo
|
||||
void
|
||||
Partition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||
off_t ptsOffset)
|
||||
off_t tableOffset)
|
||||
{
|
||||
fPTSOffset = ptsOffset;
|
||||
fPartitionTableOffset = tableOffset;
|
||||
fOffset = offset;
|
||||
fSize = size;
|
||||
fType = type;
|
||||
|
@ -347,7 +346,7 @@ Partition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
|||
void
|
||||
Partition::Unset()
|
||||
{
|
||||
fPTSOffset = 0;
|
||||
fPartitionTableOffset = 0;
|
||||
fOffset = 0;
|
||||
fSize = 0;
|
||||
fType = 0;
|
||||
|
@ -384,11 +383,11 @@ Partition::AdjustSize(off_t sessionSize)
|
|||
bool
|
||||
Partition::CheckLocation(off_t sessionSize) const
|
||||
{
|
||||
// offsets and size must be block aligned, PTS and partition must lie
|
||||
// within the session
|
||||
if (fPTSOffset % SECTOR_SIZE != 0) {
|
||||
TRACE(("Partition::CheckLocation() - bad pts offset: %lld "
|
||||
"(session: %lld)\n", fPTSOffset, sessionSize));
|
||||
// offsets and size must be block aligned, partition table and partition must
|
||||
// lie within the session
|
||||
if (fPartitionTableOffset % SECTOR_SIZE != 0) {
|
||||
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
|
||||
"(session: %lld)\n", fPartitionTableOffset, sessionSize));
|
||||
return false;
|
||||
}
|
||||
if (fOffset % SECTOR_SIZE != 0) {
|
||||
|
@ -401,9 +400,10 @@ Partition::CheckLocation(off_t sessionSize) const
|
|||
"(session: %lld)\n", fSize, sessionSize));
|
||||
return false;
|
||||
}
|
||||
if (fPTSOffset < 0 || fPTSOffset >= sessionSize) {
|
||||
TRACE(("Partition::CheckLocation() - pts offset outside session: %lld "
|
||||
"(session: %lld)\n", fPTSOffset, sessionSize));
|
||||
if (fPartitionTableOffset < 0 || fPartitionTableOffset >= sessionSize) {
|
||||
TRACE(("Partition::CheckLocation() - partition table offset outside "
|
||||
"session: %lld (session size: %lld)\n", fPartitionTableOffset,
|
||||
sessionSize));
|
||||
return false;
|
||||
}
|
||||
if (fOffset < 0) {
|
||||
|
@ -434,10 +434,11 @@ PrimaryPartition::PrimaryPartition()
|
|||
|
||||
// SetTo
|
||||
void
|
||||
PrimaryPartition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset)
|
||||
PrimaryPartition::SetTo(const partition_descriptor* descriptor,
|
||||
off_t tableOffset)
|
||||
{
|
||||
Unset();
|
||||
Partition::SetTo(descriptor, ptsOffset, 0);
|
||||
Partition::SetTo(descriptor, tableOffset, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -475,11 +476,11 @@ PrimaryPartition::Assign(const PrimaryPartition& other)
|
|||
|
||||
const LogicalPartition* otherLogical = other.fHead;
|
||||
while (otherLogical) {
|
||||
off_t ptsOffset = otherLogical->PTSOffset();
|
||||
otherLogical->GetPartitionDescriptor(&descriptor, ptsOffset);
|
||||
off_t tableOffset = otherLogical->PartitionTableOffset();
|
||||
otherLogical->GetPartitionDescriptor(&descriptor, tableOffset);
|
||||
|
||||
LogicalPartition* logical = new(nothrow) LogicalPartition(
|
||||
&descriptor, ptsOffset, this);
|
||||
&descriptor, tableOffset, this);
|
||||
if (!logical)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
|
@ -563,35 +564,36 @@ LogicalPartition::LogicalPartition()
|
|||
|
||||
// constructor
|
||||
LogicalPartition::LogicalPartition(const partition_descriptor *descriptor,
|
||||
off_t ptsOffset, PrimaryPartition *primary)
|
||||
off_t tableOffset, PrimaryPartition *primary)
|
||||
: Partition(),
|
||||
fPrimary(NULL),
|
||||
fNext(NULL),
|
||||
fPrevious(NULL)
|
||||
{
|
||||
SetTo(descriptor, ptsOffset, primary);
|
||||
SetTo(descriptor, tableOffset, primary);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
void
|
||||
LogicalPartition::SetTo(const partition_descriptor *descriptor,
|
||||
off_t ptsOffset, PrimaryPartition *primary)
|
||||
off_t tableOffset, PrimaryPartition *primary)
|
||||
{
|
||||
Unset();
|
||||
if (descriptor && primary) {
|
||||
// There are two types of LogicalPartitions. There are so called
|
||||
// "inner extended" partitions and the "real" logical partitions
|
||||
// which contain data. The "inner extended" partitions don't contain
|
||||
// data and are only used to point to the next PTS in the linked
|
||||
// list of logical partitions. For "inner extended" partitions,
|
||||
// data and are only used to point to the next partition table in the
|
||||
// linked list of logical partitions. For "inner extended" partitions,
|
||||
// the baseOffset is in relation to the (first sector of the)
|
||||
// "primary extended" partition, in another words, all inner extended
|
||||
// partitions use the same base offset for reference.
|
||||
// The data containing, real logical partitions use the offset of the
|
||||
// PTS that contains their partition descriptor as their baseOffset.
|
||||
off_t baseOffset = (descriptor->is_extended() ? primary->Offset()
|
||||
: ptsOffset);
|
||||
Partition::SetTo(descriptor, ptsOffset, baseOffset);
|
||||
// partition table that contains their partition descriptor as their
|
||||
// baseOffset.
|
||||
off_t baseOffset = descriptor->is_extended()
|
||||
? primary->Offset() : tableOffset;
|
||||
Partition::SetTo(descriptor, tableOffset, baseOffset);
|
||||
fPrimary = primary;
|
||||
}
|
||||
}
|
||||
|
@ -600,11 +602,11 @@ LogicalPartition::SetTo(const partition_descriptor *descriptor,
|
|||
// SetTo
|
||||
void
|
||||
LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
|
||||
off_t ptsOffset, PrimaryPartition *primary)
|
||||
off_t tableOffset, PrimaryPartition *primary)
|
||||
{
|
||||
Unset();
|
||||
if (primary) {
|
||||
Partition::SetTo(offset, size, type, active, ptsOffset);
|
||||
Partition::SetTo(offset, size, type, active, tableOffset);
|
||||
fPrimary = primary;
|
||||
}
|
||||
}
|
||||
|
@ -631,11 +633,13 @@ PartitionMap::PartitionMap()
|
|||
fPrimaries[i].SetIndex(i);
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
PartitionMap::~PartitionMap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Unset
|
||||
void
|
||||
PartitionMap::Unset()
|
||||
|
@ -660,7 +664,7 @@ PartitionMap::Assign(const PartitionMap& other)
|
|||
|
||||
|
||||
// PrimaryPartitionAt
|
||||
PrimaryPartition *
|
||||
PrimaryPartition*
|
||||
PartitionMap::PrimaryPartitionAt(int32 index)
|
||||
{
|
||||
PrimaryPartition *partition = NULL;
|
||||
|
@ -669,8 +673,9 @@ PartitionMap::PrimaryPartitionAt(int32 index)
|
|||
return partition;
|
||||
}
|
||||
|
||||
|
||||
// PrimaryPartitionAt
|
||||
const PrimaryPartition *
|
||||
const PrimaryPartition*
|
||||
PartitionMap::PrimaryPartitionAt(int32 index) const
|
||||
{
|
||||
const PrimaryPartition *partition = NULL;
|
||||
|
@ -717,8 +722,9 @@ PartitionMap::CountPartitions() const
|
|||
return count;
|
||||
}
|
||||
|
||||
|
||||
// CountNonEmptyPartitions
|
||||
int32
|
||||
int32
|
||||
PartitionMap::CountNonEmptyPartitions() const
|
||||
{
|
||||
int32 count = 0;
|
||||
|
@ -730,8 +736,9 @@ PartitionMap::CountNonEmptyPartitions() const
|
|||
return count;
|
||||
}
|
||||
|
||||
|
||||
// PartitionAt
|
||||
Partition *
|
||||
Partition*
|
||||
PartitionMap::PartitionAt(int32 index)
|
||||
{
|
||||
Partition *partition = NULL;
|
||||
|
@ -752,69 +759,79 @@ PartitionMap::PartitionAt(int32 index)
|
|||
return partition;
|
||||
}
|
||||
|
||||
|
||||
// PartitionAt
|
||||
const Partition *
|
||||
const Partition*
|
||||
PartitionMap::PartitionAt(int32 index) const
|
||||
{
|
||||
return const_cast<PartitionMap*>(this)->PartitionAt(index);
|
||||
}
|
||||
|
||||
|
||||
// Check
|
||||
bool
|
||||
PartitionMap::Check(off_t sessionSize) const
|
||||
{
|
||||
int32 partitionCount = CountPartitions();
|
||||
|
||||
// 1. check partition locations
|
||||
for (int32 i = 0; i < partitionCount; i++) {
|
||||
if (!PartitionAt(i)->CheckLocation(sessionSize))
|
||||
return false;
|
||||
}
|
||||
// 2. check overlapping of partitions and location of PTSs
|
||||
|
||||
// 2. check overlapping of partitions and location of partition tables
|
||||
bool result = true;
|
||||
const Partition **byOffset = new(nothrow) const Partition*[partitionCount];
|
||||
off_t *ptsOffsets = new(nothrow) off_t[partitionCount - 3];
|
||||
if (byOffset && ptsOffsets) {
|
||||
const Partition** byOffset = new(nothrow) const Partition*[partitionCount];
|
||||
off_t* tableOffsets = new(nothrow) off_t[partitionCount - 3];
|
||||
if (byOffset && tableOffsets) {
|
||||
// fill the arrays
|
||||
int32 byOffsetCount = 0;
|
||||
int32 ptsOffsetCount = 1; // primary PTS
|
||||
ptsOffsets[0] = 0; //
|
||||
int32 tableOffsetCount = 1; // primary partition table
|
||||
tableOffsets[0] = 0; //
|
||||
for (int32 i = 0; i < partitionCount; i++) {
|
||||
const Partition *partition = PartitionAt(i);
|
||||
if (!partition->IsExtended())
|
||||
byOffset[byOffsetCount++] = partition;
|
||||
// add only logical partition PTS locations
|
||||
if (i >= 4)
|
||||
ptsOffsets[ptsOffsetCount++] = partition->PTSOffset();
|
||||
|
||||
// add only logical partition partition table locations
|
||||
if (i >= 4) {
|
||||
tableOffsets[tableOffsetCount++]
|
||||
= partition->PartitionTableOffset();
|
||||
}
|
||||
}
|
||||
|
||||
// sort the arrays
|
||||
qsort(byOffset, byOffsetCount, sizeof(const Partition*),
|
||||
cmp_partition_offset);
|
||||
qsort(ptsOffsets, ptsOffsetCount, sizeof(off_t), cmp_offset);
|
||||
cmp_partition_offset);
|
||||
qsort(tableOffsets, tableOffsetCount, sizeof(off_t), cmp_offset);
|
||||
|
||||
// check for overlappings
|
||||
off_t nextOffset = 0;
|
||||
for (int32 i = 0; i < byOffsetCount; i++) {
|
||||
const Partition *partition = byOffset[i];
|
||||
if (partition->Offset() < nextOffset) {
|
||||
TRACE(("intel: PartitionMap::Check(): overlapping partitions!"
|
||||
"\n"));
|
||||
"\n"));
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
nextOffset = partition->Offset() + partition->Size();
|
||||
}
|
||||
// check uniqueness of PTS offsets and whether they lie outside of the
|
||||
// non-extended partitions
|
||||
|
||||
// check uniqueness of partition table offsets and whether they lie
|
||||
// outside of the non-extended partitions
|
||||
if (result) {
|
||||
for (int32 i = 0; i < ptsOffsetCount; i++) {
|
||||
if (i > 0 && ptsOffsets[i] == ptsOffsets[i - 1]) {
|
||||
TRACE(("intel: PartitionMap::Check(): same PTS for "
|
||||
"different extended partitions!\n"));
|
||||
for (int32 i = 0; i < tableOffsetCount; i++) {
|
||||
if (i > 0 && tableOffsets[i] == tableOffsets[i - 1]) {
|
||||
TRACE(("intel: PartitionMap::Check(): same partition talbe "
|
||||
"for different extended partitions!\n"));
|
||||
result = false;
|
||||
break;
|
||||
} else if (is_inside_partitions(ptsOffsets[i], byOffset,
|
||||
byOffsetCount)) {
|
||||
TRACE(("intel: PartitionMap::Check(): a PTS lies "
|
||||
"inside a non-extended partition!\n"));
|
||||
} else if (is_inside_partitions(tableOffsets[i], byOffset,
|
||||
byOffsetCount)) {
|
||||
TRACE(("intel: PartitionMap::Check(): a partition table "
|
||||
"lies inside a non-extended partition!\n"));
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
@ -822,11 +839,11 @@ PartitionMap::Check(off_t sessionSize) const
|
|||
}
|
||||
} else
|
||||
result = false; // no memory: assume failure
|
||||
|
||||
// cleanup
|
||||
if (byOffset)
|
||||
delete[] byOffset;
|
||||
if (ptsOffsets)
|
||||
delete[] ptsOffsets;
|
||||
delete[] byOffset;
|
||||
delete[] tableOffsets;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
* Copyright 2003-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _INTEL_PARTITION_MAP_H
|
||||
#define _INTEL_PARTITION_MAP_H
|
||||
|
||||
/*!
|
||||
\file PartitionMap.h
|
||||
/*! \file PartitionMap.h
|
||||
\ingroup intel_module
|
||||
\brief Definitions for "intel" style partitions and interface definitions
|
||||
for related classes.
|
||||
|
@ -12,9 +13,6 @@
|
|||
|
||||
// NOTE: <http://www.win.tue.nl/~aeb/partitions/partition_tables-2.html>
|
||||
|
||||
#ifndef _INTEL_PARTITION_MAP_H
|
||||
#define _INTEL_PARTITION_MAP_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#ifndef _USER_MODE
|
||||
|
@ -32,20 +30,23 @@ enum {
|
|||
SECTOR_SIZE = 512
|
||||
};
|
||||
|
||||
|
||||
// is_empty_type
|
||||
static inline bool
|
||||
is_empty_type(uint8 type)
|
||||
{
|
||||
return (type == 0x00);
|
||||
return type == 0x00;
|
||||
}
|
||||
|
||||
|
||||
// is_extended_type
|
||||
static inline bool
|
||||
is_extended_type(uint8 type)
|
||||
{
|
||||
return (type == 0x05 || type == 0x0f || type == 0x85);
|
||||
return type == 0x05 || type == 0x0f || type == 0x85;
|
||||
}
|
||||
|
||||
|
||||
// fill_buffer
|
||||
static inline void
|
||||
fill_buffer(char *buffer, uint32 length, char ch)
|
||||
|
@ -78,8 +79,8 @@ struct partition_descriptor {
|
|||
bool is_extended() const { return is_extended_type(type); }
|
||||
} _PACKED;
|
||||
|
||||
// partition_table_sector
|
||||
struct partition_table_sector {
|
||||
// partition_table
|
||||
struct partition_table {
|
||||
char pad1[446];
|
||||
partition_descriptor table[4];
|
||||
uint16 signature;
|
||||
|
@ -92,6 +93,7 @@ class Partition;
|
|||
class PrimaryPartition;
|
||||
class LogicalPartition;
|
||||
|
||||
|
||||
// PartitionType
|
||||
/*!
|
||||
\brief Class for validating partition types.
|
||||
|
@ -122,6 +124,7 @@ private:
|
|||
bool fValid;
|
||||
};
|
||||
|
||||
|
||||
// Partition
|
||||
class Partition {
|
||||
public:
|
||||
|
@ -138,13 +141,13 @@ public:
|
|||
bool IsEmpty() const { return is_empty_type(fType); }
|
||||
bool IsExtended() const { return is_extended_type(fType); }
|
||||
|
||||
// NOTE: Both PTSOffset() and Offset() are absolute with regards to the
|
||||
// NOTE: Both PartitionTableOffset() and Offset() are absolute with regards to the
|
||||
// session (usually the disk). Ie, for all primary partitions, including
|
||||
// the primary extended partition, the PTSOffset() points to the MBR (0).
|
||||
// For logical partitions, the PTSOffset() is located within the primary
|
||||
// the primary extended partition, the PartitionTableOffset() points to the MBR (0).
|
||||
// For logical partitions, the PartitionTableOffset() is located within the primary
|
||||
// extended partition, but again, the returned values are absolute with
|
||||
// regards to the session. All values are expressed in bytes.
|
||||
off_t PTSOffset() const { return fPTSOffset; }
|
||||
off_t PartitionTableOffset() const { return fPartitionTableOffset; }
|
||||
// offset of the sector containing the descriptor for this partition
|
||||
off_t Offset() const { return fOffset; }
|
||||
// start offset of the partition contents
|
||||
|
@ -156,7 +159,7 @@ public:
|
|||
void GetPartitionDescriptor(partition_descriptor *descriptor,
|
||||
off_t baseOffset) const;
|
||||
|
||||
void SetPTSOffset(off_t offset) { fPTSOffset = offset; }
|
||||
void SetPartitionTableOffset(off_t offset) { fPartitionTableOffset = offset; }
|
||||
void SetOffset(off_t offset) { fOffset = offset; }
|
||||
void SetSize(off_t size) { fSize = size; }
|
||||
void SetType(uint8 type) { fType = type; }
|
||||
|
@ -168,13 +171,14 @@ public:
|
|||
#endif
|
||||
|
||||
private:
|
||||
off_t fPTSOffset;
|
||||
off_t fPartitionTableOffset;
|
||||
off_t fOffset; // relative to the start of the session
|
||||
off_t fSize;
|
||||
uint8 fType;
|
||||
bool fActive;
|
||||
};
|
||||
|
||||
|
||||
// PrimaryPartition
|
||||
class PrimaryPartition : public Partition {
|
||||
public:
|
||||
|
@ -203,6 +207,7 @@ private:
|
|||
int32 fIndex;
|
||||
};
|
||||
|
||||
|
||||
// LogicalPartition
|
||||
class LogicalPartition : public Partition {
|
||||
public:
|
||||
|
@ -231,6 +236,7 @@ private:
|
|||
LogicalPartition *fPrevious;
|
||||
};
|
||||
|
||||
|
||||
// PartitionMap
|
||||
class PartitionMap {
|
||||
public:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
|
@ -38,66 +38,74 @@ using std::nothrow;
|
|||
// Maximal number of logical partitions per extended partition we allow.
|
||||
static const int32 kMaxLogicalPartitionCount = 128;
|
||||
|
||||
|
||||
// constructor
|
||||
PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset,
|
||||
off_t sessionSize)
|
||||
: fDeviceFD(deviceFD),
|
||||
fSessionOffset(sessionOffset),
|
||||
fSessionSize(sessionSize),
|
||||
fPTS(NULL),
|
||||
fMap(NULL)
|
||||
:
|
||||
fDeviceFD(deviceFD),
|
||||
fSessionOffset(sessionOffset),
|
||||
fSessionSize(sessionSize),
|
||||
fPartitionTable(NULL),
|
||||
fMap(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
PartitionMapParser::~PartitionMapParser()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Parse
|
||||
status_t
|
||||
PartitionMapParser::Parse(const uint8 *block, PartitionMap *map)
|
||||
PartitionMapParser::Parse(const uint8* block, PartitionMap* map)
|
||||
{
|
||||
status_t error = (map ? B_OK : B_BAD_VALUE);
|
||||
if (error == B_OK) {
|
||||
fMap = map;
|
||||
fMap->Unset();
|
||||
if (block) {
|
||||
const partition_table_sector *pts
|
||||
= (const partition_table_sector*)block;
|
||||
error = _ParsePrimary(pts);
|
||||
} else {
|
||||
partition_table_sector pts;
|
||||
error = _ReadPTS(0, &pts);
|
||||
if (error == B_OK)
|
||||
error = _ParsePrimary(&pts);
|
||||
}
|
||||
if (map == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (error == B_OK && !fMap->Check(fSessionSize))
|
||||
error = B_BAD_DATA;
|
||||
status_t error;
|
||||
|
||||
fMap = NULL;
|
||||
fMap = map;
|
||||
fMap->Unset();
|
||||
|
||||
if (block) {
|
||||
const partition_table* table = (const partition_table*)block;
|
||||
error = _ParsePrimary(table);
|
||||
} else {
|
||||
partition_table table;
|
||||
error = _ReadPartitionTable(0, &table);
|
||||
if (error == B_OK)
|
||||
error = _ParsePrimary(&table);
|
||||
}
|
||||
|
||||
if (error == B_OK && !fMap->Check(fSessionSize))
|
||||
error = B_BAD_DATA;
|
||||
|
||||
fMap = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// _ParsePrimary
|
||||
status_t
|
||||
PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
||||
PartitionMapParser::_ParsePrimary(const partition_table* table)
|
||||
{
|
||||
if (pts == NULL)
|
||||
if (table == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check the signature
|
||||
if (pts->signature != kPartitionTableSectorSignature) {
|
||||
TRACE(("intel: _ParsePrimary(): invalid PTS signature: %lx\n",
|
||||
(uint32)pts->signature));
|
||||
if (table->signature != kPartitionTableSectorSignature) {
|
||||
TRACE(("intel: _ParsePrimary(): invalid PartitionTable signature: %lx\n",
|
||||
(uint32)table->signature));
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
||||
// examine the table
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
const partition_descriptor *descriptor = &pts->table[i];
|
||||
const partition_descriptor *descriptor = &table->table[i];
|
||||
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
||||
partition->SetTo(descriptor, 0);
|
||||
|
||||
|
@ -113,9 +121,9 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
|||
}
|
||||
}
|
||||
|
||||
// allocate a PTS buffer
|
||||
fPTS = new(nothrow) partition_table_sector;
|
||||
if (fPTS == NULL)
|
||||
// allocate a partition_table buffer
|
||||
fPartitionTable = new(nothrow) partition_table;
|
||||
if (fPartitionTable == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// parse extended partitions
|
||||
|
@ -127,12 +135,13 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
|||
}
|
||||
|
||||
// cleanup
|
||||
delete fPTS;
|
||||
fPTS = NULL;
|
||||
delete fPartitionTable;
|
||||
fPartitionTable = NULL;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// _ParseExtended
|
||||
status_t
|
||||
PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
||||
|
@ -147,21 +156,21 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||
error = B_BAD_DATA;
|
||||
}
|
||||
|
||||
// read the PTS
|
||||
// read the partition table
|
||||
if (error == B_OK)
|
||||
error = _ReadPTS(offset);
|
||||
error = _ReadPartitionTable(offset);
|
||||
|
||||
// check the signature
|
||||
if (error == B_OK
|
||||
&& fPTS->signature != kPartitionTableSectorSignature) {
|
||||
TRACE(("intel: _ParseExtended(): invalid PTS signature: %lx\n",
|
||||
(uint32)fPTS->signature));
|
||||
&& fPartitionTable->signature != kPartitionTableSectorSignature) {
|
||||
TRACE(("intel: _ParseExtended(): invalid partition table signature: "
|
||||
"%lx\n", (uint32)fPartitionTable->signature));
|
||||
error = B_BAD_DATA;
|
||||
}
|
||||
|
||||
// ignore the PTS, if any error occured till now
|
||||
// ignore the partition table, if any error occured till now
|
||||
if (error != B_OK) {
|
||||
TRACE(("intel: _ParseExtended(): ignoring this PTS\n"));
|
||||
TRACE(("intel: _ParseExtended(): ignoring this partition table\n"));
|
||||
error = B_OK;
|
||||
break;
|
||||
}
|
||||
|
@ -170,15 +179,15 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||
// non-extended logical partition. All four table entries are
|
||||
// examined though. If there is no inner extended partition,
|
||||
// the end of the linked list is reached.
|
||||
// The first PTS describing both an "inner extended" parition and a
|
||||
// "data" partition (non extended and not empty) is the start sector
|
||||
// of the primary extended partition. The next PTS in the linked list
|
||||
// is the start sector of the inner extended partition described in
|
||||
// this PTS.
|
||||
// The first partition table describing both an "inner extended" parition
|
||||
// and a "data" partition (non extended and not empty) is the start
|
||||
// sector of the primary extended partition. The next partition table in
|
||||
// the linked list is the start sector of the inner extended partition
|
||||
// described in this partition table.
|
||||
LogicalPartition extended;
|
||||
LogicalPartition nonExtended;
|
||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||
const partition_descriptor *descriptor = &fPTS->table[i];
|
||||
const partition_descriptor *descriptor = &fPartitionTable->table[i];
|
||||
if (descriptor->is_empty())
|
||||
continue;
|
||||
|
||||
|
@ -215,7 +224,7 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||
error = B_BAD_DATA;
|
||||
TRACE(("intel: _ParseExtended(): Invalid partition "
|
||||
"location: pts: %lld, offset: %lld, size: %lld\n",
|
||||
partition->PTSOffset(), partition->Offset(),
|
||||
partition->PartitionTableOffset(), partition->Offset(),
|
||||
partition->Size()));
|
||||
}
|
||||
}
|
||||
|
@ -240,21 +249,26 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|||
return error;
|
||||
}
|
||||
|
||||
// _ReadPTS
|
||||
|
||||
// _ReadPartitionTable
|
||||
status_t
|
||||
PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
|
||||
PartitionMapParser::_ReadPartitionTable(off_t offset, partition_table* table)
|
||||
{
|
||||
status_t error = B_OK;
|
||||
if (!pts)
|
||||
pts = fPTS;
|
||||
int32 toRead = sizeof(partition_table_sector);
|
||||
int32 toRead = sizeof(partition_table);
|
||||
|
||||
// check the offset
|
||||
if (offset < 0 || offset + toRead > fSessionSize) {
|
||||
error = B_BAD_VALUE;
|
||||
TRACE(("intel: _ReadPTS(): bad offset: %Ld\n", offset));
|
||||
TRACE(("intel: _ReadPartitionTable(): bad offset: %Ld\n", offset));
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (table == NULL)
|
||||
table = fPartitionTable;
|
||||
|
||||
status_t error = B_OK;
|
||||
|
||||
// read
|
||||
} else if (read_pos(fDeviceFD, fSessionOffset + offset, pts, toRead)
|
||||
!= toRead) {
|
||||
if (read_pos(fDeviceFD, fSessionOffset + offset, table, toRead) != toRead) {
|
||||
#ifndef _BOOT_MODE
|
||||
error = errno;
|
||||
if (error == B_OK)
|
||||
|
@ -262,7 +276,8 @@ PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
|
|||
#else
|
||||
error = B_IO_ERROR;
|
||||
#endif
|
||||
TRACE(("intel: _ReadPTS(): reading the PTS failed: %lx\n", error));
|
||||
TRACE(("intel: _ReadPartitionTable(): reading the partition table "
|
||||
"failed: %lx\n", error));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
/*
|
||||
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold, bonefish@cs.tu-berlin.de
|
||||
*/
|
||||
|
||||
/*!
|
||||
\file PartitionMapParser.h
|
||||
/*! \file PartitionMapParser.h
|
||||
\brief Implementation of disk parser for "intel" style partitions.
|
||||
|
||||
Parser reads primary and logical partitions from the disk (according to
|
||||
|
@ -24,30 +23,32 @@
|
|||
class Partition;
|
||||
class PartitionMap;
|
||||
class PrimaryPartition;
|
||||
struct partition_table_sector;
|
||||
struct partition_table;
|
||||
|
||||
class PartitionMapParser {
|
||||
public:
|
||||
PartitionMapParser(int deviceFD, off_t sessionOffset,
|
||||
off_t sessionSize);
|
||||
~PartitionMapParser();
|
||||
public:
|
||||
PartitionMapParser(int deviceFD,
|
||||
off_t sessionOffset, off_t sessionSize);
|
||||
~PartitionMapParser();
|
||||
|
||||
status_t Parse(const uint8 *block, PartitionMap *map);
|
||||
status_t Parse(const uint8* block, PartitionMap* map);
|
||||
|
||||
int32 CountPartitions() const;
|
||||
const Partition *PartitionAt(int32 index) const;
|
||||
int32 CountPartitions() const;
|
||||
const Partition* PartitionAt(int32 index) const;
|
||||
|
||||
private:
|
||||
status_t _ParsePrimary(const partition_table_sector *pts);
|
||||
status_t _ParseExtended(PrimaryPartition *primary, off_t offset);
|
||||
status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL);
|
||||
private:
|
||||
status_t _ParsePrimary(const partition_table* table);
|
||||
status_t _ParseExtended(PrimaryPartition* primary,
|
||||
off_t offset);
|
||||
status_t _ReadPartitionTable(off_t offset,
|
||||
partition_table* table = NULL);
|
||||
|
||||
private:
|
||||
int fDeviceFD;
|
||||
off_t fSessionOffset;
|
||||
off_t fSessionSize;
|
||||
partition_table_sector *fPTS; // while parsing
|
||||
PartitionMap *fMap;
|
||||
private:
|
||||
int fDeviceFD;
|
||||
off_t fSessionOffset;
|
||||
off_t fSessionSize;
|
||||
partition_table* fPartitionTable; // while parsing
|
||||
PartitionMap* fMap;
|
||||
};
|
||||
|
||||
#endif // PARTITION_MAP_PARSER_H
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Tomas Kucera, kucerat@centrum.cz
|
||||
*/
|
||||
|
||||
#ifndef _USER_MODE
|
||||
# include <KernelExport.h>
|
||||
#endif
|
||||
#include "PartitionMapWriter.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
@ -17,11 +15,16 @@
|
|||
|
||||
#include <new>
|
||||
|
||||
#ifndef _USER_MODE
|
||||
# include <KernelExport.h>
|
||||
#endif
|
||||
|
||||
#include "PartitionMap.h"
|
||||
#include "PartitionMapWriter.h"
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
#define TRACE_ENABLED
|
||||
|
||||
#ifdef TRACE_ENABLED
|
||||
# ifdef _USER_MODE
|
||||
# define TRACE(x) printf x
|
||||
|
@ -30,11 +33,9 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
// constructor
|
||||
/*!
|
||||
\brief Creates the writer.
|
||||
/*! \brief Creates the writer.
|
||||
|
||||
\param deviceFD File descriptor.
|
||||
\param sessionOffset Disk offset of the partition with partitioning system.
|
||||
|
@ -42,26 +43,28 @@ using std::nothrow;
|
|||
*/
|
||||
PartitionMapWriter::PartitionMapWriter(int deviceFD, off_t sessionOffset,
|
||||
off_t sessionSize)
|
||||
: fDeviceFD(deviceFD),
|
||||
fSessionOffset(sessionOffset),
|
||||
fSessionSize(sessionSize),
|
||||
fMap(NULL)
|
||||
:
|
||||
fDeviceFD(deviceFD),
|
||||
fSessionOffset(sessionOffset),
|
||||
fSessionSize(sessionSize),
|
||||
fMap(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
PartitionMapWriter::~PartitionMapWriter()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// WriteMBR
|
||||
/*!
|
||||
\brief Writes Master Boot Record to the first sector of the disk.
|
||||
/*! \brief Writes Master Boot Record to the first sector of the disk.
|
||||
|
||||
If a \a block is not specified, the sector is firstly read from the disk
|
||||
and after changing relevant items it is written back to the disk.
|
||||
This allows to keep code area in MBR intact.
|
||||
\param pts Pointer to \c partition_table_sector.
|
||||
\param pts Pointer to \c partition_table.
|
||||
\param map Pointer to the PartitionMap structure describing disk partitions.
|
||||
*/
|
||||
status_t
|
||||
|
@ -72,8 +75,8 @@ PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
|
|||
|
||||
fMap = map;
|
||||
|
||||
uint8 sector[SECTOR_SIZE];
|
||||
partition_table_sector* pts = (partition_table_sector*)sector;
|
||||
uint8 sector[SECTOR_SIZE];
|
||||
partition_table* pts = (partition_table*)sector;
|
||||
|
||||
// If we shall not clear the first two sectors, we need to read the first
|
||||
// sector in, first.
|
||||
|
@ -101,9 +104,9 @@ PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
// WriteLogical
|
||||
/*!
|
||||
\brief Writes Partition Table Sector of the logical \a partition to the
|
||||
/*! \brief Writes Partition Table Sector of the logical \a partition to the
|
||||
disk.
|
||||
|
||||
This function ensures that the connection of the following linked list
|
||||
|
@ -111,21 +114,22 @@ PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
|
|||
of previous logical partitions (call this function on previous logical
|
||||
partition to ensure it).
|
||||
|
||||
\param pts Pointer to \c partition_table_sector.
|
||||
\param pts Pointer to \c partition_table.
|
||||
\param partition Pointer to the logical partition.
|
||||
*/
|
||||
status_t
|
||||
PartitionMapWriter::WriteLogical(partition_table_sector* pts,
|
||||
PartitionMapWriter::WriteLogical(partition_table* pts,
|
||||
const LogicalPartition* partition)
|
||||
{
|
||||
if (partition == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
partition_table_sector _pts;
|
||||
partition_table _pts;
|
||||
if (pts == NULL) {
|
||||
// no PTS given, use stack based PTS and read from disk first
|
||||
// no partition table given, use stack based partition table and read
|
||||
// from disk first
|
||||
pts = &_pts;
|
||||
status_t error = _ReadSector(partition->PTSOffset(), pts);
|
||||
status_t error = _ReadSector(partition->PartitionTableOffset(), pts);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
@ -134,12 +138,12 @@ PartitionMapWriter::WriteLogical(partition_table_sector* pts,
|
|||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
return _WriteSector(partition->PTSOffset(), pts);
|
||||
return _WriteSector(partition->PartitionTableOffset(), pts);
|
||||
}
|
||||
|
||||
|
||||
// WriteExtendedHead
|
||||
/*!
|
||||
\brief Writes Extended Boot Record to the first sector of Extended
|
||||
/*! \brief Writes Extended Boot Record to the first sector of Extended
|
||||
Partition.
|
||||
|
||||
Writes the head of linked list describing logical partitions.
|
||||
|
@ -147,20 +151,21 @@ PartitionMapWriter::WriteLogical(partition_table_sector* pts,
|
|||
If the \a firstPartition is not specified, it only initializes EBR and the
|
||||
linked list contains no logical partitions.
|
||||
|
||||
\param pts Pointer to \c partition_table_sector.
|
||||
\param pts Pointer to \c partition_table.
|
||||
\param firstPartition Pointer to the first logical partition.
|
||||
*/
|
||||
status_t
|
||||
PartitionMapWriter::WriteExtendedHead(partition_table_sector* pts,
|
||||
PartitionMapWriter::WriteExtendedHead(partition_table* pts,
|
||||
const LogicalPartition* firstPartition)
|
||||
{
|
||||
LogicalPartition partition;
|
||||
if (firstPartition != NULL)
|
||||
partition.SetPrimaryPartition(firstPartition->GetPrimaryPartition());
|
||||
|
||||
partition_table_sector _pts;
|
||||
partition_table _pts;
|
||||
if (pts == NULL) {
|
||||
// no PTS given, use stack based PTS and read from disk first
|
||||
// no partition table given, use stack based partition table and read
|
||||
// from disk first
|
||||
pts = &_pts;
|
||||
status_t error = _ReadSector(0, pts);
|
||||
if (error != B_OK)
|
||||
|
@ -174,11 +179,13 @@ PartitionMapWriter::WriteExtendedHead(partition_table_sector* pts,
|
|||
return _WriteSector(0, pts);
|
||||
}
|
||||
|
||||
// #pragma mark - fill a PTS in memory
|
||||
|
||||
// #pragma mark - fill a partition table in memory
|
||||
|
||||
|
||||
// _WritePrimary
|
||||
status_t
|
||||
PartitionMapWriter::_WritePrimary(partition_table_sector* pts)
|
||||
PartitionMapWriter::_WritePrimary(partition_table* pts)
|
||||
{
|
||||
if (pts == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
@ -205,9 +212,10 @@ PartitionMapWriter::_WritePrimary(partition_table_sector* pts)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// _WriteExtended
|
||||
status_t
|
||||
PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
|
||||
PartitionMapWriter::_WriteExtended(partition_table *pts,
|
||||
const LogicalPartition *partition, const LogicalPartition *next)
|
||||
{
|
||||
if (pts == NULL || partition == NULL)
|
||||
|
@ -221,7 +229,7 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
|
|||
TRACE(("intel: _WriteExtended(): Invalid partition "
|
||||
"location: pts: %lld, offset: %lld, size: %lld, "
|
||||
"fSessionSize: %lld\n",
|
||||
partition->PTSOffset(), partition->Offset(),
|
||||
partition->PartitionTableOffset(), partition->Offset(),
|
||||
partition->Size(), fSessionSize));
|
||||
return B_BAD_DATA;
|
||||
}
|
||||
|
@ -232,28 +240,31 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
|
|||
|
||||
// write the table
|
||||
partition_descriptor* descriptor = &(pts->table[0]);
|
||||
partition->GetPartitionDescriptor(descriptor, partition->PTSOffset());
|
||||
// location is relative to this partitions PTS offset
|
||||
partition->GetPartitionDescriptor(descriptor,
|
||||
partition->PartitionTableOffset());
|
||||
// location is relative to this partition's table offset
|
||||
|
||||
// Set offset and size of the next partition in the linked list.
|
||||
// This is done via a so called "inner extended" partition which is
|
||||
// only used to point to the next PTS location (start sector of the
|
||||
// inner extended partition).
|
||||
descriptor = &(pts->table[1]);
|
||||
// only used to point to the next partition table location (start sector of
|
||||
// the inner extended partition).
|
||||
descriptor = &pts->table[1];
|
||||
LogicalPartition extended;
|
||||
if (next) {
|
||||
extended.SetPTSOffset(partition->PTSOffset());
|
||||
extended.SetOffset(next->PTSOffset());
|
||||
extended.SetPartitionTableOffset(partition->PartitionTableOffset());
|
||||
extended.SetOffset(next->PartitionTableOffset());
|
||||
|
||||
// Strictly speaking, the size is not relevant and just needs to
|
||||
// be non-zero. But some operating systems check the size of
|
||||
// inner extended partitions and it needs to include the next data
|
||||
// partition. Therefor the size is the size of the next data partition
|
||||
// plus the offset between the next PTS and the data partition start
|
||||
// offset. This assumes of course that the start offset is behind
|
||||
// the PTS offset, which is actually not dictated by a minimal
|
||||
// plus the offset between the next partition table and the data
|
||||
// partition start offset.
|
||||
// This assumes of course that the start offset is behind the partition
|
||||
// table offset, which is actually not dictated by a minimal
|
||||
// specification.
|
||||
extended.SetSize(next->Size() + (next->Offset() - next->PTSOffset()));
|
||||
extended.SetSize(next->Size()
|
||||
+ (next->Offset() - next->PartitionTableOffset()));
|
||||
|
||||
// Use the same extended partition type as the primary extended
|
||||
// partition.
|
||||
|
@ -275,15 +286,17 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - to/from disk
|
||||
|
||||
|
||||
// _ReadSector
|
||||
/*! \brief Reads the sector from the disk.
|
||||
*/
|
||||
status_t
|
||||
PartitionMapWriter::_ReadSector(off_t offset, partition_table_sector* pts)
|
||||
PartitionMapWriter::_ReadSector(off_t offset, partition_table* pts)
|
||||
{
|
||||
int32 toRead = sizeof(partition_table_sector);
|
||||
int32 toRead = sizeof(partition_table);
|
||||
// same as SECTOR_SIZE actually
|
||||
|
||||
// check the offset
|
||||
|
@ -302,21 +315,22 @@ PartitionMapWriter::_ReadSector(off_t offset, partition_table_sector* pts)
|
|||
#else
|
||||
status_t error = B_IO_ERROR;
|
||||
#endif
|
||||
TRACE(("intel: _ReadSector(): reading the PTS failed: %lx\n", error));
|
||||
TRACE(("intel: _ReadSector(): reading the partition table failed: %lx\n",
|
||||
error));
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// _WriteSector
|
||||
/*! \brief Writes the sector to the disk.
|
||||
*/
|
||||
status_t
|
||||
PartitionMapWriter::_WriteSector(off_t offset,
|
||||
const partition_table_sector* pts)
|
||||
PartitionMapWriter::_WriteSector(off_t offset, const partition_table* pts)
|
||||
{
|
||||
int32 toWrite = sizeof(partition_table_sector);
|
||||
int32 toWrite = sizeof(partition_table);
|
||||
// same as SECTOR_SIZE actually
|
||||
|
||||
// check the offset
|
||||
|
@ -333,7 +347,8 @@ PartitionMapWriter::_WriteSector(off_t offset,
|
|||
if (error == B_OK)
|
||||
error = B_IO_ERROR;
|
||||
|
||||
TRACE(("intel: _WriteSector(): writing the PTS failed: %lx\n", error));
|
||||
TRACE(("intel: _WriteSector(): writing the partition table failed: "
|
||||
"%lx\n", error));
|
||||
return error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
|
@ -26,7 +26,7 @@
|
|||
|
||||
class PartitionMap;
|
||||
class LogicalPartition;
|
||||
struct partition_table_sector;
|
||||
struct partition_table;
|
||||
|
||||
/*!
|
||||
\brief Writer for "Intel" style partitions.
|
||||
|
@ -41,21 +41,21 @@ public:
|
|||
|
||||
status_t WriteMBR(const PartitionMap* map,
|
||||
bool clearSectors);
|
||||
status_t WriteLogical(partition_table_sector* pts,
|
||||
status_t WriteLogical(partition_table* pts,
|
||||
const LogicalPartition* partition);
|
||||
status_t WriteExtendedHead(partition_table_sector* pts,
|
||||
status_t WriteExtendedHead(partition_table* pts,
|
||||
const LogicalPartition* firstPartition);
|
||||
|
||||
private:
|
||||
status_t _WritePrimary(partition_table_sector* pts);
|
||||
status_t _WriteExtended(partition_table_sector* pts,
|
||||
status_t _WritePrimary(partition_table* pts);
|
||||
status_t _WriteExtended(partition_table* pts,
|
||||
const LogicalPartition* partition,
|
||||
const LogicalPartition* next);
|
||||
|
||||
status_t _ReadSector(off_t offset,
|
||||
partition_table_sector* pts);
|
||||
partition_table* pts);
|
||||
status_t _WriteSector(off_t offset,
|
||||
const partition_table_sector* pts);
|
||||
const partition_table* pts);
|
||||
|
||||
private:
|
||||
int fDeviceFD;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
|
@ -7,6 +7,8 @@
|
|||
* Tomas Kucera, kucerat@centrum.cz
|
||||
*/
|
||||
|
||||
#include "write_support.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -30,7 +32,6 @@
|
|||
//#define TRACE(x) ;
|
||||
#define TRACE(x) dprintf x
|
||||
|
||||
|
||||
// Maximal size of move buffer (in sectors).
|
||||
static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
|
||||
|
||||
|
@ -112,21 +113,21 @@ pm_is_sub_system_for(partition_data *partition)
|
|||
|
||||
|
||||
// sector_align (auxiliary function)
|
||||
static inline
|
||||
off_t
|
||||
static inline off_t
|
||||
sector_align(off_t offset)
|
||||
{
|
||||
return offset / SECTOR_SIZE * SECTOR_SIZE;
|
||||
}
|
||||
|
||||
|
||||
// sector_align_up (auxiliary function)
|
||||
static inline
|
||||
off_t
|
||||
static inline off_t
|
||||
sector_align_up(off_t offset)
|
||||
{
|
||||
return (offset + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE;
|
||||
}
|
||||
|
||||
|
||||
// validate_resize (auxiliary function)
|
||||
static bool
|
||||
validate_resize(partition_data *partition, off_t *size)
|
||||
|
@ -164,6 +165,7 @@ validate_resize(partition_data *partition, off_t *size)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// pm_validate_resize
|
||||
bool
|
||||
pm_validate_resize(partition_data *partition, off_t *size)
|
||||
|
@ -176,21 +178,23 @@ pm_validate_resize(partition_data *partition, off_t *size)
|
|||
return validate_resize(partition, size);
|
||||
}
|
||||
|
||||
|
||||
// get_offset_ep (auxiliary function)
|
||||
static inline off_t
|
||||
get_offset_ep(const partition_data *partition)
|
||||
{
|
||||
LogicalPartition *logical = (LogicalPartition *)partition->cookie;
|
||||
off_t diff_offset = logical->Offset() - logical->PTSOffset();
|
||||
off_t diff_offset = logical->Offset() - logical->PartitionTableOffset();
|
||||
return partition->offset - diff_offset;
|
||||
}
|
||||
|
||||
|
||||
// get_size_ep (auxiliary function)
|
||||
static inline off_t
|
||||
get_size_ep(const partition_data *partition)
|
||||
{
|
||||
LogicalPartition *logical = (LogicalPartition *)partition->cookie;
|
||||
off_t diff_offset = logical->Offset() - logical->PTSOffset();
|
||||
off_t diff_offset = logical->Offset() - logical->PartitionTableOffset();
|
||||
return partition->size + diff_offset;
|
||||
}
|
||||
|
||||
|
@ -234,6 +238,7 @@ get_sibling_partitions_pm(partition_data *partition,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// get_sibling_partitions_ep (auxiliary function)
|
||||
/*!
|
||||
according to childOffset returns previous and next sibling or NULL
|
||||
|
@ -273,6 +278,7 @@ get_sibling_partitions_ep(partition_data *partition,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// validate_resize_child (auxiliary function)
|
||||
static bool
|
||||
validate_resize_child(partition_data *partition, partition_data *child,
|
||||
|
@ -310,6 +316,7 @@ validate_resize_child(partition_data *partition, partition_data *child,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// pm_validate_resize_child
|
||||
bool
|
||||
pm_validate_resize_child(partition_data *partition, partition_data *child,
|
||||
|
@ -324,6 +331,7 @@ pm_validate_resize_child(partition_data *partition, partition_data *child,
|
|||
child->size, size, get_sibling_partitions_pm);
|
||||
}
|
||||
|
||||
|
||||
// pm_validate_move
|
||||
bool
|
||||
pm_validate_move(partition_data *partition, off_t *start)
|
||||
|
@ -336,6 +344,7 @@ pm_validate_move(partition_data *partition, off_t *start)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// validate_move_child (auxiliary function)
|
||||
static bool
|
||||
validate_move_child(partition_data *partition, partition_data *child,
|
||||
|
@ -424,6 +433,7 @@ is_type_valid_pm(const char *type, partition_data *partition,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// pm_validate_set_type
|
||||
bool
|
||||
pm_validate_set_type(partition_data *partition, const char *type)
|
||||
|
@ -465,6 +475,7 @@ pm_validate_initialize(partition_data *partition, char *name,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// validate_create_child_partition (auxiliary function)
|
||||
static bool
|
||||
validate_create_child_partition(partition_data *partition, off_t *start,
|
||||
|
@ -507,6 +518,7 @@ validate_create_child_partition(partition_data *partition, off_t *start,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// pm_validate_create_child
|
||||
/*!
|
||||
index - returns position of the new partition (first free record in MBR)
|
||||
|
@ -555,18 +567,23 @@ pm_validate_create_child(partition_data *partition, off_t *start, off_t *size,
|
|||
get_sibling_partitions_pm);
|
||||
}
|
||||
|
||||
|
||||
// cmp_partition_position
|
||||
static int
|
||||
cmp_partition_position(const void *o1, const void *o2) {
|
||||
cmp_partition_position(const void *o1, const void *o2)
|
||||
{
|
||||
off_t offset1 = ((PartitionPosition*)o1)->offset;
|
||||
off_t offset2 = ((PartitionPosition*)o2)->offset;
|
||||
|
||||
if (offset1 < offset2)
|
||||
return -1;
|
||||
else if (offset1 > offset2)
|
||||
if (offset1 > offset2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// fill_partitionable_spaces_buffer_pm
|
||||
/*!
|
||||
positions - output buffer with sufficient size
|
||||
|
@ -588,6 +605,7 @@ fill_partitionable_spaces_buffer_pm(partition_data *partition,
|
|||
return partition_count;
|
||||
}
|
||||
|
||||
|
||||
// fill_partitionable_spaces_buffer_ep
|
||||
/*!
|
||||
positions - output buffer with sufficient size
|
||||
|
@ -609,6 +627,7 @@ fill_partitionable_spaces_buffer_ep(partition_data *partition,
|
|||
return partition_count;
|
||||
}
|
||||
|
||||
|
||||
// get_partitionable_spaces (auxiliary function)
|
||||
static status_t
|
||||
get_partitionable_spaces(partition_data *partition,
|
||||
|
@ -672,6 +691,7 @@ get_partitionable_spaces(partition_data *partition,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_get_partitionable_spaces
|
||||
status_t
|
||||
pm_get_partitionable_spaces(partition_data *partition,
|
||||
|
@ -692,6 +712,7 @@ pm_get_partitionable_spaces(partition_data *partition,
|
|||
0, 0);
|
||||
}
|
||||
|
||||
|
||||
// pm_get_next_supported_type
|
||||
status_t
|
||||
pm_get_next_supported_type(partition_data *partition, int32 *cookie,
|
||||
|
@ -930,6 +951,7 @@ pm_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_resize_child
|
||||
status_t
|
||||
pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
||||
|
@ -983,6 +1005,7 @@ pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_move
|
||||
status_t
|
||||
pm_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
|
||||
|
@ -1011,6 +1034,7 @@ pm_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// allocate_buffer (auxiliary function)
|
||||
/*!
|
||||
tries to allocate buffer with the size: blockSize * tryAlloc
|
||||
|
@ -1033,6 +1057,7 @@ allocate_buffer(uint32 blockSize, int32 tryAlloc, int32 *allocated)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// move_block (auxiliary function)
|
||||
static status_t
|
||||
move_block(int fd, off_t fromOffset, off_t toOffset, uint8 *buffer, int32 size)
|
||||
|
@ -1058,13 +1083,14 @@ move_block(int fd, off_t fromOffset, off_t toOffset, uint8 *buffer, int32 size)
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
// move_partition (auxiliary function)
|
||||
static status_t
|
||||
move_partition(int fd, off_t fromOffset, off_t toOffset, off_t size,
|
||||
uint8 *buffer, int32 buffer_size, disk_job_id job)
|
||||
{
|
||||
// TODO: This should be a service function of the DDM!
|
||||
// TODO: This seems to be broken if source and destination overlap.
|
||||
// TODO: This should be a service function of the DDM!
|
||||
// TODO: This seems to be broken if source and destination overlap.
|
||||
status_t error = B_OK;
|
||||
off_t cycleCount = size / buffer_size;
|
||||
int32 remainingSize = size - cycleCount * buffer_size;
|
||||
|
@ -1083,6 +1109,7 @@ move_partition(int fd, off_t fromOffset, off_t toOffset, off_t size,
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
// pm_move_child
|
||||
status_t
|
||||
pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
||||
|
@ -1107,7 +1134,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
if (!map || !primary)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
off_t validatedOffset = offset;
|
||||
if (!pm_validate_move_child(partition, child, &validatedOffset))
|
||||
return B_BAD_VALUE;
|
||||
|
@ -1124,7 +1151,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
return B_NO_MEMORY;
|
||||
|
||||
// partition moving
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
update_disk_device_job_progress(job, 0.0);
|
||||
status_t error = B_OK;
|
||||
error = move_partition(fd, child->offset, validatedOffset, child->size,
|
||||
|
@ -1152,6 +1179,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_set_type
|
||||
status_t
|
||||
pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
||||
|
@ -1188,14 +1216,14 @@ pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||
// this is impossible
|
||||
if (!ptype.IsValid() || ptype.IsEmpty())
|
||||
return false;
|
||||
// TODO: Incompatible return value!
|
||||
// TODO: Incompatible return value!
|
||||
|
||||
// setting type to the partition
|
||||
update_disk_device_job_progress(job, 0.0);
|
||||
uint8 oldType = primary->Type();
|
||||
primary->SetType(ptype.Type());
|
||||
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
PartitionMapWriter writer(fd, 0, partition->size);
|
||||
// TODO: disk size?
|
||||
status_t error = writer.WriteMBR(map, false);
|
||||
|
@ -1251,13 +1279,15 @@ pm_initialize(int fd, partition_id partitionID, const char *name,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_create_child
|
||||
/*! childID is used for the return value, but is also an optional input
|
||||
parameter -- -1 to be ignored
|
||||
*/
|
||||
status_t
|
||||
pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
||||
const char *type, const char *parameters, disk_job_id job,
|
||||
partition_id *childID)
|
||||
// childID is used for the return value, but is also an optional input
|
||||
// parameter -- -1 to be ignored
|
||||
{
|
||||
TRACE(("intel: pm_create_child\n"));
|
||||
|
||||
|
@ -1277,7 +1307,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
return B_BAD_VALUE;
|
||||
|
||||
// validate the offset, size and get index of the new partition
|
||||
// TODO: The parameters have already been checked and must not be altered!
|
||||
// TODO: The parameters have already been checked and must not be altered!
|
||||
off_t validatedOffset = offset;
|
||||
off_t validatedSize = size;
|
||||
int32 index = 0;
|
||||
|
@ -1303,7 +1333,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
PartitionType ptype;
|
||||
ptype.SetType(type);
|
||||
|
||||
primary->SetPTSOffset(0);
|
||||
primary->SetPartitionTableOffset(0);
|
||||
primary->SetOffset(validatedOffset);
|
||||
primary->SetSize(validatedSize);
|
||||
primary->SetType(ptype.Type());
|
||||
|
@ -1313,7 +1343,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
// write changes to disk
|
||||
PartitionMapWriter writer(fd, 0, partition->size);
|
||||
// TODO: disk size or 2 * SECTOR_SIZE?
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
status_t error = writer.WriteMBR(map, false);
|
||||
if (error != B_OK) {
|
||||
// putting into previous state
|
||||
|
@ -1342,6 +1372,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// pm_delete_child
|
||||
status_t
|
||||
pm_delete_child(int fd, partition_id partitionID, partition_id childID,
|
||||
|
@ -1375,7 +1406,7 @@ pm_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||
// write changes to disk
|
||||
PartitionMapWriter writer(fd, 0, partition->size);
|
||||
// TODO: disk size or 2 * SECTOR_SIZE?
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
// TODO: The partition is not supposed to be locked at this point!
|
||||
status_t error = writer.WriteMBR(map, false);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
@ -1464,6 +1495,7 @@ ep_validate_resize(partition_data *partition, off_t *size)
|
|||
return validate_resize(partition, size);
|
||||
}
|
||||
|
||||
|
||||
// ep_validate_resize_child
|
||||
bool
|
||||
ep_validate_resize_child(partition_data *partition, partition_data *child,
|
||||
|
@ -1484,6 +1516,7 @@ ep_validate_resize_child(partition_data *partition, partition_data *child,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ep_validate_move
|
||||
bool
|
||||
ep_validate_move(partition_data *partition, off_t *start)
|
||||
|
@ -1496,10 +1529,11 @@ ep_validate_move(partition_data *partition, off_t *start)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ep_validate_move_child
|
||||
bool
|
||||
ep_validate_move_child(partition_data *partition, partition_data *child,
|
||||
off_t *_start)
|
||||
off_t *_start)
|
||||
{
|
||||
TRACE(("intel: ep_validate_move_child\n"));
|
||||
|
||||
|
@ -1518,6 +1552,7 @@ ep_validate_move_child(partition_data *partition, partition_data *child,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// is_type_valid_ep (auxiliary function)
|
||||
static inline bool
|
||||
is_type_valid_ep(const char *type)
|
||||
|
@ -1528,6 +1563,7 @@ is_type_valid_ep(const char *type)
|
|||
return (ptype.IsValid() && !ptype.IsEmpty() && !ptype.IsExtended());
|
||||
}
|
||||
|
||||
|
||||
// ep_validate_set_type
|
||||
bool
|
||||
ep_validate_set_type(partition_data *partition, const char *type)
|
||||
|
@ -1541,6 +1577,7 @@ ep_validate_set_type(partition_data *partition, const char *type)
|
|||
return is_type_valid_ep(type);
|
||||
}
|
||||
|
||||
|
||||
// ep_validate_initialize
|
||||
bool
|
||||
ep_validate_initialize(partition_data *partition, char *name,
|
||||
|
@ -1558,6 +1595,7 @@ ep_validate_initialize(partition_data *partition, char *name,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ep_validate_create_child
|
||||
bool
|
||||
ep_validate_create_child(partition_data *partition, off_t *_start, off_t *_size,
|
||||
|
@ -1599,6 +1637,7 @@ ep_validate_create_child(partition_data *partition, off_t *_start, off_t *_size,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ep_get_partitionable_spaces
|
||||
status_t
|
||||
ep_get_partitionable_spaces(partition_data *partition,
|
||||
|
@ -1621,6 +1660,7 @@ ep_get_partitionable_spaces(partition_data *partition,
|
|||
PTS_OFFSET * SECTOR_SIZE);
|
||||
}
|
||||
|
||||
|
||||
// ep_get_next_supported_type
|
||||
status_t
|
||||
ep_get_next_supported_type(partition_data *partition, int32 *cookie,
|
||||
|
@ -1661,6 +1701,7 @@ ep_get_next_supported_type(partition_data *partition, int32 *cookie,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_shadow_changed
|
||||
status_t
|
||||
ep_shadow_changed(partition_data *partition, partition_data *child,
|
||||
|
@ -1698,7 +1739,7 @@ ep_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
return B_BAD_VALUE;
|
||||
|
||||
// validate the new size
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
off_t validatedSize = size;
|
||||
if (!ep_validate_resize(partition, &validatedSize))
|
||||
return B_BAD_VALUE;
|
||||
|
@ -1706,7 +1747,7 @@ ep_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
// update data stuctures
|
||||
update_disk_device_job_progress(job, 0.0);
|
||||
|
||||
// TODO: partition->size is not supposed to be touched.
|
||||
// TODO: partition->size is not supposed to be touched.
|
||||
partition->size = validatedSize;
|
||||
partition->content_size = validatedSize;
|
||||
|
||||
|
@ -1716,6 +1757,7 @@ ep_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_resize_child
|
||||
status_t
|
||||
ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
||||
|
@ -1739,7 +1781,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
return B_BAD_VALUE;
|
||||
|
||||
// validate the new size
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
off_t validatedSize = size;
|
||||
if (!ep_validate_resize_child(partition, child, &validatedSize))
|
||||
return B_BAD_VALUE;
|
||||
|
@ -1751,7 +1793,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
logical->SetSize(validatedSize);
|
||||
|
||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = writer.WriteLogical(NULL, logical);
|
||||
if (error != B_OK) {
|
||||
// putting into previous state
|
||||
|
@ -1773,6 +1815,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_move
|
||||
status_t
|
||||
ep_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
|
||||
|
@ -1792,7 +1835,7 @@ ep_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
|
|||
return B_BAD_VALUE;
|
||||
|
||||
// validate the new start
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
if (!ep_validate_move(partition, &offset))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
@ -1800,6 +1843,7 @@ ep_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_move_child
|
||||
status_t
|
||||
ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
||||
|
@ -1823,7 +1867,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
if (!logical)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
off_t validatedOffset = offset;
|
||||
if (!ep_validate_move_child(partition, child, &validatedOffset))
|
||||
return B_BAD_VALUE;
|
||||
|
@ -1843,8 +1887,8 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
// partition moving
|
||||
update_disk_device_job_progress(job, 0.0);
|
||||
status_t error = B_OK;
|
||||
// move partition with its header (PTS table)
|
||||
off_t pts_offset = logical->Offset() - logical->PTSOffset();
|
||||
// move partition with its header (partition table)
|
||||
off_t pts_offset = logical->Offset() - logical->PartitionTableOffset();
|
||||
error = move_partition(fd, child->offset - pts_offset,
|
||||
validatedOffset - pts_offset, child->size + pts_offset, buffer,
|
||||
allocated * SECTOR_SIZE, job);
|
||||
|
@ -1856,12 +1900,12 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
// updating data structure
|
||||
child->offset = validatedOffset;
|
||||
logical->SetOffset(logical->Offset() + diffOffset);
|
||||
logical->SetPTSOffset(logical->PTSOffset() + diffOffset);
|
||||
logical->SetPartitionTableOffset(logical->PartitionTableOffset() + diffOffset);
|
||||
|
||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
||||
// TODO: If partition->offset is > prev->offset, then writing
|
||||
// the previous logical partition table will fail!
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
error = writer.WriteLogical(NULL, logical);
|
||||
if (error != B_OK)
|
||||
// something went wrong - this is fatal (partition has been moved)
|
||||
|
@ -1880,6 +1924,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_set_type
|
||||
status_t
|
||||
ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
||||
|
@ -1902,7 +1947,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||
if (!logical)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
if (!ep_validate_set_type(child, type))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
|
@ -1922,7 +1967,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||
logical->SetType(ptype.Type());
|
||||
|
||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = writer.WriteLogical(NULL, logical);
|
||||
if (error != B_OK) {
|
||||
// something went wrong - putting into previous state
|
||||
|
@ -1941,6 +1986,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_initialize
|
||||
status_t
|
||||
ep_initialize(int fd, partition_id partitionID, const char *name,
|
||||
|
@ -1977,12 +2023,12 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
|
|||
partition->content_cookie = primary;
|
||||
|
||||
// we delete code area in EBR - nothing should be there
|
||||
partition_table_sector pts;
|
||||
pts.clear_code_area();
|
||||
partition_table table;
|
||||
table.clear_code_area();
|
||||
|
||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = writer.WriteExtendedHead(&pts, NULL);
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = writer.WriteExtendedHead(&table, NULL);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
|
@ -1992,6 +2038,7 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_create_child
|
||||
/*!
|
||||
childID is used for the return value, but is also an optional input
|
||||
|
@ -2021,7 +2068,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
return B_BAD_VALUE;
|
||||
|
||||
// validate the offset, size and get index of the new partition
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
// TODO: The parameter has already been checked and must not be altered!
|
||||
off_t validatedOffset = offset;
|
||||
off_t validatedSize = size;
|
||||
int32 index = 0;
|
||||
|
@ -2047,7 +2094,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
PartitionType ptype;
|
||||
ptype.SetType(type);
|
||||
|
||||
logical->SetPTSOffset(validatedOffset - PTS_OFFSET * SECTOR_SIZE
|
||||
logical->SetPartitionTableOffset(validatedOffset - PTS_OFFSET * SECTOR_SIZE
|
||||
- partition->offset);
|
||||
logical->SetOffset(validatedOffset - partition->offset);
|
||||
logical->SetSize(validatedSize);
|
||||
|
@ -2056,14 +2103,15 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
logical->SetActive(false);
|
||||
|
||||
// we delete code area in EBR - nothing should be there
|
||||
partition_table_sector pts;
|
||||
pts.clear_code_area();
|
||||
partition_table table;
|
||||
table.clear_code_area();
|
||||
|
||||
// write changes to disk
|
||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
||||
// TODO: wrong offset range, writing prev will fail
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = writer.WriteLogical(&pts, logical);
|
||||
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = writer.WriteLogical(&table, logical);
|
||||
if (error != B_OK) {
|
||||
// putting into previous state
|
||||
delete_partition(child->id);
|
||||
|
@ -2103,6 +2151,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ep_delete_child
|
||||
status_t
|
||||
ep_delete_child(int fd, partition_id partitionID, partition_id childID,
|
||||
|
@ -2141,7 +2190,7 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
||||
// TODO: Check offset range! Writing "prev/next_logical"?
|
||||
// Should be parent->offset and parent->size?
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
// TODO: The partition is not supposed to be locked here!
|
||||
status_t error = prev_logical ? writer.WriteLogical(NULL, prev_logical)
|
||||
: writer.WriteExtendedHead(NULL, next_logical);
|
||||
if (error != B_OK)
|
||||
|
|
Loading…
Reference in New Issue