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