* 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:
Axel Dörfler 2009-04-14 11:56:21 +00:00
parent d88bc21991
commit b41bbb4a46
7 changed files with 374 additions and 271 deletions

View File

@ -1,13 +1,12 @@
/*
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold, bonefish@cs.tu-berlin.de
*/
/*!
\file PartitionMap.cpp
/*! \file PartitionMap.cpp
\brief Definitions for "intel" style partitions and implementation
of related classes.
*/
@ -292,7 +291,7 @@ PartitionType::FindNext()
// constructor
Partition::Partition()
:
fPTSOffset(0),
fPartitionTableOffset(0),
fOffset(0),
fSize(0),
fType(0),
@ -301,21 +300,21 @@ Partition::Partition()
}
// constructor
Partition::Partition(const partition_descriptor *descriptor,off_t ptsOffset,
Partition::Partition(const partition_descriptor* descriptor, off_t tableOffset,
off_t baseOffset)
:
fPTSOffset(0),
fPartitionTableOffset(0),
fOffset(0),
fSize(0),
fType(0),
fActive(false)
{
SetTo(descriptor, ptsOffset, baseOffset);
SetTo(descriptor, tableOffset, baseOffset);
}
// SetTo
void
Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
Partition::SetTo(const partition_descriptor *descriptor, off_t tableOffset,
off_t baseOffset)
{
TRACE(("Partition::SetTo(): active: %x\n", descriptor->active));
@ -323,16 +322,16 @@ Partition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset,
(off_t)descriptor->size * SECTOR_SIZE,
descriptor->type,
descriptor->active,
ptsOffset);
tableOffset);
}
// SetTo
void
Partition::SetTo(off_t offset, off_t size, uint8 type, bool active,
off_t ptsOffset)
off_t tableOffset)
{
fPTSOffset = ptsOffset;
fPartitionTableOffset = tableOffset;
fOffset = offset;
fSize = size;
fType = type;
@ -347,7 +346,7 @@ Partition::SetTo(off_t offset, off_t size, uint8 type, bool active,
void
Partition::Unset()
{
fPTSOffset = 0;
fPartitionTableOffset = 0;
fOffset = 0;
fSize = 0;
fType = 0;
@ -384,11 +383,11 @@ Partition::AdjustSize(off_t sessionSize)
bool
Partition::CheckLocation(off_t sessionSize) const
{
// offsets and size must be block aligned, PTS and partition must lie
// within the session
if (fPTSOffset % SECTOR_SIZE != 0) {
TRACE(("Partition::CheckLocation() - bad pts offset: %lld "
"(session: %lld)\n", fPTSOffset, sessionSize));
// offsets and size must be block aligned, partition table and partition must
// lie within the session
if (fPartitionTableOffset % SECTOR_SIZE != 0) {
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
"(session: %lld)\n", fPartitionTableOffset, sessionSize));
return false;
}
if (fOffset % SECTOR_SIZE != 0) {
@ -401,9 +400,10 @@ Partition::CheckLocation(off_t sessionSize) const
"(session: %lld)\n", fSize, sessionSize));
return false;
}
if (fPTSOffset < 0 || fPTSOffset >= sessionSize) {
TRACE(("Partition::CheckLocation() - pts offset outside session: %lld "
"(session: %lld)\n", fPTSOffset, sessionSize));
if (fPartitionTableOffset < 0 || fPartitionTableOffset >= sessionSize) {
TRACE(("Partition::CheckLocation() - partition table offset outside "
"session: %lld (session size: %lld)\n", fPartitionTableOffset,
sessionSize));
return false;
}
if (fOffset < 0) {
@ -434,10 +434,11 @@ PrimaryPartition::PrimaryPartition()
// SetTo
void
PrimaryPartition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset)
PrimaryPartition::SetTo(const partition_descriptor* descriptor,
off_t tableOffset)
{
Unset();
Partition::SetTo(descriptor, ptsOffset, 0);
Partition::SetTo(descriptor, tableOffset, 0);
}
@ -475,11 +476,11 @@ PrimaryPartition::Assign(const PrimaryPartition& other)
const LogicalPartition* otherLogical = other.fHead;
while (otherLogical) {
off_t ptsOffset = otherLogical->PTSOffset();
otherLogical->GetPartitionDescriptor(&descriptor, ptsOffset);
off_t tableOffset = otherLogical->PartitionTableOffset();
otherLogical->GetPartitionDescriptor(&descriptor, tableOffset);
LogicalPartition* logical = new(nothrow) LogicalPartition(
&descriptor, ptsOffset, this);
&descriptor, tableOffset, this);
if (!logical)
return B_NO_MEMORY;
@ -563,35 +564,36 @@ LogicalPartition::LogicalPartition()
// constructor
LogicalPartition::LogicalPartition(const partition_descriptor *descriptor,
off_t ptsOffset, PrimaryPartition *primary)
off_t tableOffset, PrimaryPartition *primary)
: Partition(),
fPrimary(NULL),
fNext(NULL),
fPrevious(NULL)
{
SetTo(descriptor, ptsOffset, primary);
SetTo(descriptor, tableOffset, primary);
}
// SetTo
void
LogicalPartition::SetTo(const partition_descriptor *descriptor,
off_t ptsOffset, PrimaryPartition *primary)
off_t tableOffset, PrimaryPartition *primary)
{
Unset();
if (descriptor && primary) {
// There are two types of LogicalPartitions. There are so called
// "inner extended" partitions and the "real" logical partitions
// which contain data. The "inner extended" partitions don't contain
// data and are only used to point to the next PTS in the linked
// list of logical partitions. For "inner extended" partitions,
// data and are only used to point to the next partition table in the
// linked list of logical partitions. For "inner extended" partitions,
// the baseOffset is in relation to the (first sector of the)
// "primary extended" partition, in another words, all inner extended
// partitions use the same base offset for reference.
// The data containing, real logical partitions use the offset of the
// PTS that contains their partition descriptor as their baseOffset.
off_t baseOffset = (descriptor->is_extended() ? primary->Offset()
: ptsOffset);
Partition::SetTo(descriptor, ptsOffset, baseOffset);
// partition table that contains their partition descriptor as their
// baseOffset.
off_t baseOffset = descriptor->is_extended()
? primary->Offset() : tableOffset;
Partition::SetTo(descriptor, tableOffset, baseOffset);
fPrimary = primary;
}
}
@ -600,11 +602,11 @@ LogicalPartition::SetTo(const partition_descriptor *descriptor,
// SetTo
void
LogicalPartition::SetTo(off_t offset, off_t size, uint8 type, bool active,
off_t ptsOffset, PrimaryPartition *primary)
off_t tableOffset, PrimaryPartition *primary)
{
Unset();
if (primary) {
Partition::SetTo(offset, size, type, active, ptsOffset);
Partition::SetTo(offset, size, type, active, tableOffset);
fPrimary = primary;
}
}
@ -631,11 +633,13 @@ PartitionMap::PartitionMap()
fPrimaries[i].SetIndex(i);
}
// destructor
PartitionMap::~PartitionMap()
{
}
// Unset
void
PartitionMap::Unset()
@ -660,7 +664,7 @@ PartitionMap::Assign(const PartitionMap& other)
// PrimaryPartitionAt
PrimaryPartition *
PrimaryPartition*
PartitionMap::PrimaryPartitionAt(int32 index)
{
PrimaryPartition *partition = NULL;
@ -669,8 +673,9 @@ PartitionMap::PrimaryPartitionAt(int32 index)
return partition;
}
// PrimaryPartitionAt
const PrimaryPartition *
const PrimaryPartition*
PartitionMap::PrimaryPartitionAt(int32 index) const
{
const PrimaryPartition *partition = NULL;
@ -717,8 +722,9 @@ PartitionMap::CountPartitions() const
return count;
}
// CountNonEmptyPartitions
int32
int32
PartitionMap::CountNonEmptyPartitions() const
{
int32 count = 0;
@ -730,8 +736,9 @@ PartitionMap::CountNonEmptyPartitions() const
return count;
}
// PartitionAt
Partition *
Partition*
PartitionMap::PartitionAt(int32 index)
{
Partition *partition = NULL;
@ -752,69 +759,79 @@ PartitionMap::PartitionAt(int32 index)
return partition;
}
// PartitionAt
const Partition *
const Partition*
PartitionMap::PartitionAt(int32 index) const
{
return const_cast<PartitionMap*>(this)->PartitionAt(index);
}
// Check
bool
PartitionMap::Check(off_t sessionSize) const
{
int32 partitionCount = CountPartitions();
// 1. check partition locations
for (int32 i = 0; i < partitionCount; i++) {
if (!PartitionAt(i)->CheckLocation(sessionSize))
return false;
}
// 2. check overlapping of partitions and location of PTSs
// 2. check overlapping of partitions and location of partition tables
bool result = true;
const Partition **byOffset = new(nothrow) const Partition*[partitionCount];
off_t *ptsOffsets = new(nothrow) off_t[partitionCount - 3];
if (byOffset && ptsOffsets) {
const Partition** byOffset = new(nothrow) const Partition*[partitionCount];
off_t* tableOffsets = new(nothrow) off_t[partitionCount - 3];
if (byOffset && tableOffsets) {
// fill the arrays
int32 byOffsetCount = 0;
int32 ptsOffsetCount = 1; // primary PTS
ptsOffsets[0] = 0; //
int32 tableOffsetCount = 1; // primary partition table
tableOffsets[0] = 0; //
for (int32 i = 0; i < partitionCount; i++) {
const Partition *partition = PartitionAt(i);
if (!partition->IsExtended())
byOffset[byOffsetCount++] = partition;
// add only logical partition PTS locations
if (i >= 4)
ptsOffsets[ptsOffsetCount++] = partition->PTSOffset();
// add only logical partition partition table locations
if (i >= 4) {
tableOffsets[tableOffsetCount++]
= partition->PartitionTableOffset();
}
}
// sort the arrays
qsort(byOffset, byOffsetCount, sizeof(const Partition*),
cmp_partition_offset);
qsort(ptsOffsets, ptsOffsetCount, sizeof(off_t), cmp_offset);
cmp_partition_offset);
qsort(tableOffsets, tableOffsetCount, sizeof(off_t), cmp_offset);
// check for overlappings
off_t nextOffset = 0;
for (int32 i = 0; i < byOffsetCount; i++) {
const Partition *partition = byOffset[i];
if (partition->Offset() < nextOffset) {
TRACE(("intel: PartitionMap::Check(): overlapping partitions!"
"\n"));
"\n"));
result = false;
break;
}
nextOffset = partition->Offset() + partition->Size();
}
// check uniqueness of PTS offsets and whether they lie outside of the
// non-extended partitions
// check uniqueness of partition table offsets and whether they lie
// outside of the non-extended partitions
if (result) {
for (int32 i = 0; i < ptsOffsetCount; i++) {
if (i > 0 && ptsOffsets[i] == ptsOffsets[i - 1]) {
TRACE(("intel: PartitionMap::Check(): same PTS for "
"different extended partitions!\n"));
for (int32 i = 0; i < tableOffsetCount; i++) {
if (i > 0 && tableOffsets[i] == tableOffsets[i - 1]) {
TRACE(("intel: PartitionMap::Check(): same partition talbe "
"for different extended partitions!\n"));
result = false;
break;
} else if (is_inside_partitions(ptsOffsets[i], byOffset,
byOffsetCount)) {
TRACE(("intel: PartitionMap::Check(): a PTS lies "
"inside a non-extended partition!\n"));
} else if (is_inside_partitions(tableOffsets[i], byOffset,
byOffsetCount)) {
TRACE(("intel: PartitionMap::Check(): a partition table "
"lies inside a non-extended partition!\n"));
result = false;
break;
}
@ -822,11 +839,11 @@ PartitionMap::Check(off_t sessionSize) const
}
} else
result = false; // no memory: assume failure
// cleanup
if (byOffset)
delete[] byOffset;
if (ptsOffsets)
delete[] ptsOffsets;
delete[] byOffset;
delete[] tableOffsets;
return result;
}

View File

@ -2,9 +2,10 @@
* Copyright 2003-2007, Ingo Weinhold, bonefish@cs.tu-berlin.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _INTEL_PARTITION_MAP_H
#define _INTEL_PARTITION_MAP_H
/*!
\file PartitionMap.h
/*! \file PartitionMap.h
\ingroup intel_module
\brief Definitions for "intel" style partitions and interface definitions
for related classes.
@ -12,9 +13,6 @@
// NOTE: <http://www.win.tue.nl/~aeb/partitions/partition_tables-2.html>
#ifndef _INTEL_PARTITION_MAP_H
#define _INTEL_PARTITION_MAP_H
#include <SupportDefs.h>
#ifndef _USER_MODE
@ -32,20 +30,23 @@ enum {
SECTOR_SIZE = 512
};
// is_empty_type
static inline bool
is_empty_type(uint8 type)
{
return (type == 0x00);
return type == 0x00;
}
// is_extended_type
static inline bool
is_extended_type(uint8 type)
{
return (type == 0x05 || type == 0x0f || type == 0x85);
return type == 0x05 || type == 0x0f || type == 0x85;
}
// fill_buffer
static inline void
fill_buffer(char *buffer, uint32 length, char ch)
@ -78,8 +79,8 @@ struct partition_descriptor {
bool is_extended() const { return is_extended_type(type); }
} _PACKED;
// partition_table_sector
struct partition_table_sector {
// partition_table
struct partition_table {
char pad1[446];
partition_descriptor table[4];
uint16 signature;
@ -92,6 +93,7 @@ class Partition;
class PrimaryPartition;
class LogicalPartition;
// PartitionType
/*!
\brief Class for validating partition types.
@ -122,6 +124,7 @@ private:
bool fValid;
};
// Partition
class Partition {
public:
@ -138,13 +141,13 @@ public:
bool IsEmpty() const { return is_empty_type(fType); }
bool IsExtended() const { return is_extended_type(fType); }
// NOTE: Both PTSOffset() and Offset() are absolute with regards to the
// NOTE: Both PartitionTableOffset() and Offset() are absolute with regards to the
// session (usually the disk). Ie, for all primary partitions, including
// the primary extended partition, the PTSOffset() points to the MBR (0).
// For logical partitions, the PTSOffset() is located within the primary
// the primary extended partition, the PartitionTableOffset() points to the MBR (0).
// For logical partitions, the PartitionTableOffset() is located within the primary
// extended partition, but again, the returned values are absolute with
// regards to the session. All values are expressed in bytes.
off_t PTSOffset() const { return fPTSOffset; }
off_t PartitionTableOffset() const { return fPartitionTableOffset; }
// offset of the sector containing the descriptor for this partition
off_t Offset() const { return fOffset; }
// start offset of the partition contents
@ -156,7 +159,7 @@ public:
void GetPartitionDescriptor(partition_descriptor *descriptor,
off_t baseOffset) const;
void SetPTSOffset(off_t offset) { fPTSOffset = offset; }
void SetPartitionTableOffset(off_t offset) { fPartitionTableOffset = offset; }
void SetOffset(off_t offset) { fOffset = offset; }
void SetSize(off_t size) { fSize = size; }
void SetType(uint8 type) { fType = type; }
@ -168,13 +171,14 @@ public:
#endif
private:
off_t fPTSOffset;
off_t fPartitionTableOffset;
off_t fOffset; // relative to the start of the session
off_t fSize;
uint8 fType;
bool fActive;
};
// PrimaryPartition
class PrimaryPartition : public Partition {
public:
@ -203,6 +207,7 @@ private:
int32 fIndex;
};
// LogicalPartition
class LogicalPartition : public Partition {
public:
@ -231,6 +236,7 @@ private:
LogicalPartition *fPrevious;
};
// PartitionMap
class PartitionMap {
public:

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2008, Haiku, Inc. All Rights Reserved.
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -38,66 +38,74 @@ using std::nothrow;
// Maximal number of logical partitions per extended partition we allow.
static const int32 kMaxLogicalPartitionCount = 128;
// constructor
PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset,
off_t sessionSize)
: fDeviceFD(deviceFD),
fSessionOffset(sessionOffset),
fSessionSize(sessionSize),
fPTS(NULL),
fMap(NULL)
:
fDeviceFD(deviceFD),
fSessionOffset(sessionOffset),
fSessionSize(sessionSize),
fPartitionTable(NULL),
fMap(NULL)
{
}
// destructor
PartitionMapParser::~PartitionMapParser()
{
}
// Parse
status_t
PartitionMapParser::Parse(const uint8 *block, PartitionMap *map)
PartitionMapParser::Parse(const uint8* block, PartitionMap* map)
{
status_t error = (map ? B_OK : B_BAD_VALUE);
if (error == B_OK) {
fMap = map;
fMap->Unset();
if (block) {
const partition_table_sector *pts
= (const partition_table_sector*)block;
error = _ParsePrimary(pts);
} else {
partition_table_sector pts;
error = _ReadPTS(0, &pts);
if (error == B_OK)
error = _ParsePrimary(&pts);
}
if (map == NULL)
return B_BAD_VALUE;
if (error == B_OK && !fMap->Check(fSessionSize))
error = B_BAD_DATA;
status_t error;
fMap = NULL;
fMap = map;
fMap->Unset();
if (block) {
const partition_table* table = (const partition_table*)block;
error = _ParsePrimary(table);
} else {
partition_table table;
error = _ReadPartitionTable(0, &table);
if (error == B_OK)
error = _ParsePrimary(&table);
}
if (error == B_OK && !fMap->Check(fSessionSize))
error = B_BAD_DATA;
fMap = NULL;
return error;
}
// _ParsePrimary
status_t
PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
PartitionMapParser::_ParsePrimary(const partition_table* table)
{
if (pts == NULL)
if (table == NULL)
return B_BAD_VALUE;
// check the signature
if (pts->signature != kPartitionTableSectorSignature) {
TRACE(("intel: _ParsePrimary(): invalid PTS signature: %lx\n",
(uint32)pts->signature));
if (table->signature != kPartitionTableSectorSignature) {
TRACE(("intel: _ParsePrimary(): invalid PartitionTable signature: %lx\n",
(uint32)table->signature));
return B_BAD_DATA;
}
// examine the table
for (int32 i = 0; i < 4; i++) {
const partition_descriptor *descriptor = &pts->table[i];
const partition_descriptor *descriptor = &table->table[i];
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
partition->SetTo(descriptor, 0);
@ -113,9 +121,9 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
}
}
// allocate a PTS buffer
fPTS = new(nothrow) partition_table_sector;
if (fPTS == NULL)
// allocate a partition_table buffer
fPartitionTable = new(nothrow) partition_table;
if (fPartitionTable == NULL)
return B_NO_MEMORY;
// parse extended partitions
@ -127,12 +135,13 @@ PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
}
// cleanup
delete fPTS;
fPTS = NULL;
delete fPartitionTable;
fPartitionTable = NULL;
return error;
}
// _ParseExtended
status_t
PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
@ -147,21 +156,21 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
error = B_BAD_DATA;
}
// read the PTS
// read the partition table
if (error == B_OK)
error = _ReadPTS(offset);
error = _ReadPartitionTable(offset);
// check the signature
if (error == B_OK
&& fPTS->signature != kPartitionTableSectorSignature) {
TRACE(("intel: _ParseExtended(): invalid PTS signature: %lx\n",
(uint32)fPTS->signature));
&& fPartitionTable->signature != kPartitionTableSectorSignature) {
TRACE(("intel: _ParseExtended(): invalid partition table signature: "
"%lx\n", (uint32)fPartitionTable->signature));
error = B_BAD_DATA;
}
// ignore the PTS, if any error occured till now
// ignore the partition table, if any error occured till now
if (error != B_OK) {
TRACE(("intel: _ParseExtended(): ignoring this PTS\n"));
TRACE(("intel: _ParseExtended(): ignoring this partition table\n"));
error = B_OK;
break;
}
@ -170,15 +179,15 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
// non-extended logical partition. All four table entries are
// examined though. If there is no inner extended partition,
// the end of the linked list is reached.
// The first PTS describing both an "inner extended" parition and a
// "data" partition (non extended and not empty) is the start sector
// of the primary extended partition. The next PTS in the linked list
// is the start sector of the inner extended partition described in
// this PTS.
// The first partition table describing both an "inner extended" parition
// and a "data" partition (non extended and not empty) is the start
// sector of the primary extended partition. The next partition table in
// the linked list is the start sector of the inner extended partition
// described in this partition table.
LogicalPartition extended;
LogicalPartition nonExtended;
for (int32 i = 0; error == B_OK && i < 4; i++) {
const partition_descriptor *descriptor = &fPTS->table[i];
const partition_descriptor *descriptor = &fPartitionTable->table[i];
if (descriptor->is_empty())
continue;
@ -215,7 +224,7 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
error = B_BAD_DATA;
TRACE(("intel: _ParseExtended(): Invalid partition "
"location: pts: %lld, offset: %lld, size: %lld\n",
partition->PTSOffset(), partition->Offset(),
partition->PartitionTableOffset(), partition->Offset(),
partition->Size()));
}
}
@ -240,21 +249,26 @@ PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
return error;
}
// _ReadPTS
// _ReadPartitionTable
status_t
PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
PartitionMapParser::_ReadPartitionTable(off_t offset, partition_table* table)
{
status_t error = B_OK;
if (!pts)
pts = fPTS;
int32 toRead = sizeof(partition_table_sector);
int32 toRead = sizeof(partition_table);
// check the offset
if (offset < 0 || offset + toRead > fSessionSize) {
error = B_BAD_VALUE;
TRACE(("intel: _ReadPTS(): bad offset: %Ld\n", offset));
TRACE(("intel: _ReadPartitionTable(): bad offset: %Ld\n", offset));
return B_BAD_VALUE;
}
if (table == NULL)
table = fPartitionTable;
status_t error = B_OK;
// read
} else if (read_pos(fDeviceFD, fSessionOffset + offset, pts, toRead)
!= toRead) {
if (read_pos(fDeviceFD, fSessionOffset + offset, table, toRead) != toRead) {
#ifndef _BOOT_MODE
error = errno;
if (error == B_OK)
@ -262,7 +276,8 @@ PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
#else
error = B_IO_ERROR;
#endif
TRACE(("intel: _ReadPTS(): reading the PTS failed: %lx\n", error));
TRACE(("intel: _ReadPartitionTable(): reading the partition table "
"failed: %lx\n", error));
}
return error;
}

View File

@ -1,13 +1,12 @@
/*
* Copyright 2003-2006, Haiku, Inc. All Rights Reserved.
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold, bonefish@cs.tu-berlin.de
*/
/*!
\file PartitionMapParser.h
/*! \file PartitionMapParser.h
\brief Implementation of disk parser for "intel" style partitions.
Parser reads primary and logical partitions from the disk (according to
@ -24,30 +23,32 @@
class Partition;
class PartitionMap;
class PrimaryPartition;
struct partition_table_sector;
struct partition_table;
class PartitionMapParser {
public:
PartitionMapParser(int deviceFD, off_t sessionOffset,
off_t sessionSize);
~PartitionMapParser();
public:
PartitionMapParser(int deviceFD,
off_t sessionOffset, off_t sessionSize);
~PartitionMapParser();
status_t Parse(const uint8 *block, PartitionMap *map);
status_t Parse(const uint8* block, PartitionMap* map);
int32 CountPartitions() const;
const Partition *PartitionAt(int32 index) const;
int32 CountPartitions() const;
const Partition* PartitionAt(int32 index) const;
private:
status_t _ParsePrimary(const partition_table_sector *pts);
status_t _ParseExtended(PrimaryPartition *primary, off_t offset);
status_t _ReadPTS(off_t offset, partition_table_sector *pts = NULL);
private:
status_t _ParsePrimary(const partition_table* table);
status_t _ParseExtended(PrimaryPartition* primary,
off_t offset);
status_t _ReadPartitionTable(off_t offset,
partition_table* table = NULL);
private:
int fDeviceFD;
off_t fSessionOffset;
off_t fSessionSize;
partition_table_sector *fPTS; // while parsing
PartitionMap *fMap;
private:
int fDeviceFD;
off_t fSessionOffset;
off_t fSessionSize;
partition_table* fPartitionTable; // while parsing
PartitionMap* fMap;
};
#endif // PARTITION_MAP_PARSER_H

View File

@ -1,14 +1,12 @@
/*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Tomas Kucera, kucerat@centrum.cz
*/
#ifndef _USER_MODE
# include <KernelExport.h>
#endif
#include "PartitionMapWriter.h"
#include <errno.h>
#include <stdio.h>
@ -17,11 +15,16 @@
#include <new>
#ifndef _USER_MODE
# include <KernelExport.h>
#endif
#include "PartitionMap.h"
#include "PartitionMapWriter.h"
using std::nothrow;
#define TRACE_ENABLED
#ifdef TRACE_ENABLED
# ifdef _USER_MODE
# define TRACE(x) printf x
@ -30,11 +33,9 @@
# endif
#endif
using std::nothrow;
// constructor
/*!
\brief Creates the writer.
/*! \brief Creates the writer.
\param deviceFD File descriptor.
\param sessionOffset Disk offset of the partition with partitioning system.
@ -42,26 +43,28 @@ using std::nothrow;
*/
PartitionMapWriter::PartitionMapWriter(int deviceFD, off_t sessionOffset,
off_t sessionSize)
: fDeviceFD(deviceFD),
fSessionOffset(sessionOffset),
fSessionSize(sessionSize),
fMap(NULL)
:
fDeviceFD(deviceFD),
fSessionOffset(sessionOffset),
fSessionSize(sessionSize),
fMap(NULL)
{
}
// destructor
PartitionMapWriter::~PartitionMapWriter()
{
}
// WriteMBR
/*!
\brief Writes Master Boot Record to the first sector of the disk.
/*! \brief Writes Master Boot Record to the first sector of the disk.
If a \a block is not specified, the sector is firstly read from the disk
and after changing relevant items it is written back to the disk.
This allows to keep code area in MBR intact.
\param pts Pointer to \c partition_table_sector.
\param pts Pointer to \c partition_table.
\param map Pointer to the PartitionMap structure describing disk partitions.
*/
status_t
@ -72,8 +75,8 @@ PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
fMap = map;
uint8 sector[SECTOR_SIZE];
partition_table_sector* pts = (partition_table_sector*)sector;
uint8 sector[SECTOR_SIZE];
partition_table* pts = (partition_table*)sector;
// If we shall not clear the first two sectors, we need to read the first
// sector in, first.
@ -101,9 +104,9 @@ PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
return error;
}
// WriteLogical
/*!
\brief Writes Partition Table Sector of the logical \a partition to the
/*! \brief Writes Partition Table Sector of the logical \a partition to the
disk.
This function ensures that the connection of the following linked list
@ -111,21 +114,22 @@ PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
of previous logical partitions (call this function on previous logical
partition to ensure it).
\param pts Pointer to \c partition_table_sector.
\param pts Pointer to \c partition_table.
\param partition Pointer to the logical partition.
*/
status_t
PartitionMapWriter::WriteLogical(partition_table_sector* pts,
PartitionMapWriter::WriteLogical(partition_table* pts,
const LogicalPartition* partition)
{
if (partition == NULL)
return B_BAD_VALUE;
partition_table_sector _pts;
partition_table _pts;
if (pts == NULL) {
// no PTS given, use stack based PTS and read from disk first
// no partition table given, use stack based partition table and read
// from disk first
pts = &_pts;
status_t error = _ReadSector(partition->PTSOffset(), pts);
status_t error = _ReadSector(partition->PartitionTableOffset(), pts);
if (error != B_OK)
return error;
}
@ -134,12 +138,12 @@ PartitionMapWriter::WriteLogical(partition_table_sector* pts,
if (error != B_OK)
return error;
return _WriteSector(partition->PTSOffset(), pts);
return _WriteSector(partition->PartitionTableOffset(), pts);
}
// WriteExtendedHead
/*!
\brief Writes Extended Boot Record to the first sector of Extended
/*! \brief Writes Extended Boot Record to the first sector of Extended
Partition.
Writes the head of linked list describing logical partitions.
@ -147,20 +151,21 @@ PartitionMapWriter::WriteLogical(partition_table_sector* pts,
If the \a firstPartition is not specified, it only initializes EBR and the
linked list contains no logical partitions.
\param pts Pointer to \c partition_table_sector.
\param pts Pointer to \c partition_table.
\param firstPartition Pointer to the first logical partition.
*/
status_t
PartitionMapWriter::WriteExtendedHead(partition_table_sector* pts,
PartitionMapWriter::WriteExtendedHead(partition_table* pts,
const LogicalPartition* firstPartition)
{
LogicalPartition partition;
if (firstPartition != NULL)
partition.SetPrimaryPartition(firstPartition->GetPrimaryPartition());
partition_table_sector _pts;
partition_table _pts;
if (pts == NULL) {
// no PTS given, use stack based PTS and read from disk first
// no partition table given, use stack based partition table and read
// from disk first
pts = &_pts;
status_t error = _ReadSector(0, pts);
if (error != B_OK)
@ -174,11 +179,13 @@ PartitionMapWriter::WriteExtendedHead(partition_table_sector* pts,
return _WriteSector(0, pts);
}
// #pragma mark - fill a PTS in memory
// #pragma mark - fill a partition table in memory
// _WritePrimary
status_t
PartitionMapWriter::_WritePrimary(partition_table_sector* pts)
PartitionMapWriter::_WritePrimary(partition_table* pts)
{
if (pts == NULL)
return B_BAD_VALUE;
@ -205,9 +212,10 @@ PartitionMapWriter::_WritePrimary(partition_table_sector* pts)
return B_OK;
}
// _WriteExtended
status_t
PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
PartitionMapWriter::_WriteExtended(partition_table *pts,
const LogicalPartition *partition, const LogicalPartition *next)
{
if (pts == NULL || partition == NULL)
@ -221,7 +229,7 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
TRACE(("intel: _WriteExtended(): Invalid partition "
"location: pts: %lld, offset: %lld, size: %lld, "
"fSessionSize: %lld\n",
partition->PTSOffset(), partition->Offset(),
partition->PartitionTableOffset(), partition->Offset(),
partition->Size(), fSessionSize));
return B_BAD_DATA;
}
@ -232,28 +240,31 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
// write the table
partition_descriptor* descriptor = &(pts->table[0]);
partition->GetPartitionDescriptor(descriptor, partition->PTSOffset());
// location is relative to this partitions PTS offset
partition->GetPartitionDescriptor(descriptor,
partition->PartitionTableOffset());
// location is relative to this partition's table offset
// Set offset and size of the next partition in the linked list.
// This is done via a so called "inner extended" partition which is
// only used to point to the next PTS location (start sector of the
// inner extended partition).
descriptor = &(pts->table[1]);
// only used to point to the next partition table location (start sector of
// the inner extended partition).
descriptor = &pts->table[1];
LogicalPartition extended;
if (next) {
extended.SetPTSOffset(partition->PTSOffset());
extended.SetOffset(next->PTSOffset());
extended.SetPartitionTableOffset(partition->PartitionTableOffset());
extended.SetOffset(next->PartitionTableOffset());
// Strictly speaking, the size is not relevant and just needs to
// be non-zero. But some operating systems check the size of
// inner extended partitions and it needs to include the next data
// partition. Therefor the size is the size of the next data partition
// plus the offset between the next PTS and the data partition start
// offset. This assumes of course that the start offset is behind
// the PTS offset, which is actually not dictated by a minimal
// plus the offset between the next partition table and the data
// partition start offset.
// This assumes of course that the start offset is behind the partition
// table offset, which is actually not dictated by a minimal
// specification.
extended.SetSize(next->Size() + (next->Offset() - next->PTSOffset()));
extended.SetSize(next->Size()
+ (next->Offset() - next->PartitionTableOffset()));
// Use the same extended partition type as the primary extended
// partition.
@ -275,15 +286,17 @@ PartitionMapWriter::_WriteExtended(partition_table_sector *pts,
return B_OK;
}
// #pragma mark - to/from disk
// _ReadSector
/*! \brief Reads the sector from the disk.
*/
status_t
PartitionMapWriter::_ReadSector(off_t offset, partition_table_sector* pts)
PartitionMapWriter::_ReadSector(off_t offset, partition_table* pts)
{
int32 toRead = sizeof(partition_table_sector);
int32 toRead = sizeof(partition_table);
// same as SECTOR_SIZE actually
// check the offset
@ -302,21 +315,22 @@ PartitionMapWriter::_ReadSector(off_t offset, partition_table_sector* pts)
#else
status_t error = B_IO_ERROR;
#endif
TRACE(("intel: _ReadSector(): reading the PTS failed: %lx\n", error));
TRACE(("intel: _ReadSector(): reading the partition table failed: %lx\n",
error));
return error;
}
return B_OK;
}
// _WriteSector
/*! \brief Writes the sector to the disk.
*/
status_t
PartitionMapWriter::_WriteSector(off_t offset,
const partition_table_sector* pts)
PartitionMapWriter::_WriteSector(off_t offset, const partition_table* pts)
{
int32 toWrite = sizeof(partition_table_sector);
int32 toWrite = sizeof(partition_table);
// same as SECTOR_SIZE actually
// check the offset
@ -333,7 +347,8 @@ PartitionMapWriter::_WriteSector(off_t offset,
if (error == B_OK)
error = B_IO_ERROR;
TRACE(("intel: _WriteSector(): writing the PTS failed: %lx\n", error));
TRACE(("intel: _WriteSector(): writing the partition table failed: "
"%lx\n", error));
return error;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -26,7 +26,7 @@
class PartitionMap;
class LogicalPartition;
struct partition_table_sector;
struct partition_table;
/*!
\brief Writer for "Intel" style partitions.
@ -41,21 +41,21 @@ public:
status_t WriteMBR(const PartitionMap* map,
bool clearSectors);
status_t WriteLogical(partition_table_sector* pts,
status_t WriteLogical(partition_table* pts,
const LogicalPartition* partition);
status_t WriteExtendedHead(partition_table_sector* pts,
status_t WriteExtendedHead(partition_table* pts,
const LogicalPartition* firstPartition);
private:
status_t _WritePrimary(partition_table_sector* pts);
status_t _WriteExtended(partition_table_sector* pts,
status_t _WritePrimary(partition_table* pts);
status_t _WriteExtended(partition_table* pts,
const LogicalPartition* partition,
const LogicalPartition* next);
status_t _ReadSector(off_t offset,
partition_table_sector* pts);
partition_table* pts);
status_t _WriteSector(off_t offset,
const partition_table_sector* pts);
const partition_table* pts);
private:
int fDeviceFD;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
* Copyright 2003-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
@ -7,6 +7,8 @@
* Tomas Kucera, kucerat@centrum.cz
*/
#include "write_support.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@ -30,7 +32,6 @@
//#define TRACE(x) ;
#define TRACE(x) dprintf x
// Maximal size of move buffer (in sectors).
static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
@ -112,21 +113,21 @@ pm_is_sub_system_for(partition_data *partition)
// sector_align (auxiliary function)
static inline
off_t
static inline off_t
sector_align(off_t offset)
{
return offset / SECTOR_SIZE * SECTOR_SIZE;
}
// sector_align_up (auxiliary function)
static inline
off_t
static inline off_t
sector_align_up(off_t offset)
{
return (offset + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE;
}
// validate_resize (auxiliary function)
static bool
validate_resize(partition_data *partition, off_t *size)
@ -164,6 +165,7 @@ validate_resize(partition_data *partition, off_t *size)
return true;
}
// pm_validate_resize
bool
pm_validate_resize(partition_data *partition, off_t *size)
@ -176,21 +178,23 @@ pm_validate_resize(partition_data *partition, off_t *size)
return validate_resize(partition, size);
}
// get_offset_ep (auxiliary function)
static inline off_t
get_offset_ep(const partition_data *partition)
{
LogicalPartition *logical = (LogicalPartition *)partition->cookie;
off_t diff_offset = logical->Offset() - logical->PTSOffset();
off_t diff_offset = logical->Offset() - logical->PartitionTableOffset();
return partition->offset - diff_offset;
}
// get_size_ep (auxiliary function)
static inline off_t
get_size_ep(const partition_data *partition)
{
LogicalPartition *logical = (LogicalPartition *)partition->cookie;
off_t diff_offset = logical->Offset() - logical->PTSOffset();
off_t diff_offset = logical->Offset() - logical->PartitionTableOffset();
return partition->size + diff_offset;
}
@ -234,6 +238,7 @@ get_sibling_partitions_pm(partition_data *partition,
}
}
// get_sibling_partitions_ep (auxiliary function)
/*!
according to childOffset returns previous and next sibling or NULL
@ -273,6 +278,7 @@ get_sibling_partitions_ep(partition_data *partition,
}
}
// validate_resize_child (auxiliary function)
static bool
validate_resize_child(partition_data *partition, partition_data *child,
@ -310,6 +316,7 @@ validate_resize_child(partition_data *partition, partition_data *child,
return true;
}
// pm_validate_resize_child
bool
pm_validate_resize_child(partition_data *partition, partition_data *child,
@ -324,6 +331,7 @@ pm_validate_resize_child(partition_data *partition, partition_data *child,
child->size, size, get_sibling_partitions_pm);
}
// pm_validate_move
bool
pm_validate_move(partition_data *partition, off_t *start)
@ -336,6 +344,7 @@ pm_validate_move(partition_data *partition, off_t *start)
return true;
}
// validate_move_child (auxiliary function)
static bool
validate_move_child(partition_data *partition, partition_data *child,
@ -424,6 +433,7 @@ is_type_valid_pm(const char *type, partition_data *partition,
return true;
}
// pm_validate_set_type
bool
pm_validate_set_type(partition_data *partition, const char *type)
@ -465,6 +475,7 @@ pm_validate_initialize(partition_data *partition, char *name,
return true;
}
// validate_create_child_partition (auxiliary function)
static bool
validate_create_child_partition(partition_data *partition, off_t *start,
@ -507,6 +518,7 @@ validate_create_child_partition(partition_data *partition, off_t *start,
return true;
}
// pm_validate_create_child
/*!
index - returns position of the new partition (first free record in MBR)
@ -555,18 +567,23 @@ pm_validate_create_child(partition_data *partition, off_t *start, off_t *size,
get_sibling_partitions_pm);
}
// cmp_partition_position
static int
cmp_partition_position(const void *o1, const void *o2) {
cmp_partition_position(const void *o1, const void *o2)
{
off_t offset1 = ((PartitionPosition*)o1)->offset;
off_t offset2 = ((PartitionPosition*)o2)->offset;
if (offset1 < offset2)
return -1;
else if (offset1 > offset2)
if (offset1 > offset2)
return 1;
return 0;
}
// fill_partitionable_spaces_buffer_pm
/*!
positions - output buffer with sufficient size
@ -588,6 +605,7 @@ fill_partitionable_spaces_buffer_pm(partition_data *partition,
return partition_count;
}
// fill_partitionable_spaces_buffer_ep
/*!
positions - output buffer with sufficient size
@ -609,6 +627,7 @@ fill_partitionable_spaces_buffer_ep(partition_data *partition,
return partition_count;
}
// get_partitionable_spaces (auxiliary function)
static status_t
get_partitionable_spaces(partition_data *partition,
@ -672,6 +691,7 @@ get_partitionable_spaces(partition_data *partition,
return B_OK;
}
// pm_get_partitionable_spaces
status_t
pm_get_partitionable_spaces(partition_data *partition,
@ -692,6 +712,7 @@ pm_get_partitionable_spaces(partition_data *partition,
0, 0);
}
// pm_get_next_supported_type
status_t
pm_get_next_supported_type(partition_data *partition, int32 *cookie,
@ -930,6 +951,7 @@ pm_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
return B_OK;
}
// pm_resize_child
status_t
pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
@ -983,6 +1005,7 @@ pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
return B_OK;
}
// pm_move
status_t
pm_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
@ -1011,6 +1034,7 @@ pm_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
return B_OK;
}
// allocate_buffer (auxiliary function)
/*!
tries to allocate buffer with the size: blockSize * tryAlloc
@ -1033,6 +1057,7 @@ allocate_buffer(uint32 blockSize, int32 tryAlloc, int32 *allocated)
return NULL;
}
// move_block (auxiliary function)
static status_t
move_block(int fd, off_t fromOffset, off_t toOffset, uint8 *buffer, int32 size)
@ -1058,13 +1083,14 @@ move_block(int fd, off_t fromOffset, off_t toOffset, uint8 *buffer, int32 size)
return error;
}
// move_partition (auxiliary function)
static status_t
move_partition(int fd, off_t fromOffset, off_t toOffset, off_t size,
uint8 *buffer, int32 buffer_size, disk_job_id job)
{
// TODO: This should be a service function of the DDM!
// TODO: This seems to be broken if source and destination overlap.
// TODO: This should be a service function of the DDM!
// TODO: This seems to be broken if source and destination overlap.
status_t error = B_OK;
off_t cycleCount = size / buffer_size;
int32 remainingSize = size - cycleCount * buffer_size;
@ -1083,6 +1109,7 @@ move_partition(int fd, off_t fromOffset, off_t toOffset, off_t size,
return error;
}
// pm_move_child
status_t
pm_move_child(int fd, partition_id partitionID, partition_id childID,
@ -1107,7 +1134,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
if (!map || !primary)
return B_BAD_VALUE;
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
off_t validatedOffset = offset;
if (!pm_validate_move_child(partition, child, &validatedOffset))
return B_BAD_VALUE;
@ -1124,7 +1151,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
return B_NO_MEMORY;
// partition moving
// TODO: The partition is not supposed to be locked at this point!
// TODO: The partition is not supposed to be locked at this point!
update_disk_device_job_progress(job, 0.0);
status_t error = B_OK;
error = move_partition(fd, child->offset, validatedOffset, child->size,
@ -1152,6 +1179,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
return B_OK;
}
// pm_set_type
status_t
pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
@ -1188,14 +1216,14 @@ pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
// this is impossible
if (!ptype.IsValid() || ptype.IsEmpty())
return false;
// TODO: Incompatible return value!
// TODO: Incompatible return value!
// setting type to the partition
update_disk_device_job_progress(job, 0.0);
uint8 oldType = primary->Type();
primary->SetType(ptype.Type());
// TODO: The partition is not supposed to be locked at this point!
// TODO: The partition is not supposed to be locked at this point!
PartitionMapWriter writer(fd, 0, partition->size);
// TODO: disk size?
status_t error = writer.WriteMBR(map, false);
@ -1251,13 +1279,15 @@ pm_initialize(int fd, partition_id partitionID, const char *name,
return B_OK;
}
// pm_create_child
/*! childID is used for the return value, but is also an optional input
parameter -- -1 to be ignored
*/
status_t
pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
const char *type, const char *parameters, disk_job_id job,
partition_id *childID)
// childID is used for the return value, but is also an optional input
// parameter -- -1 to be ignored
{
TRACE(("intel: pm_create_child\n"));
@ -1277,7 +1307,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
return B_BAD_VALUE;
// validate the offset, size and get index of the new partition
// TODO: The parameters have already been checked and must not be altered!
// TODO: The parameters have already been checked and must not be altered!
off_t validatedOffset = offset;
off_t validatedSize = size;
int32 index = 0;
@ -1303,7 +1333,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
PartitionType ptype;
ptype.SetType(type);
primary->SetPTSOffset(0);
primary->SetPartitionTableOffset(0);
primary->SetOffset(validatedOffset);
primary->SetSize(validatedSize);
primary->SetType(ptype.Type());
@ -1313,7 +1343,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
// write changes to disk
PartitionMapWriter writer(fd, 0, partition->size);
// TODO: disk size or 2 * SECTOR_SIZE?
// TODO: The partition is not supposed to be locked at this point!
// TODO: The partition is not supposed to be locked at this point!
status_t error = writer.WriteMBR(map, false);
if (error != B_OK) {
// putting into previous state
@ -1342,6 +1372,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
return B_OK;
}
// pm_delete_child
status_t
pm_delete_child(int fd, partition_id partitionID, partition_id childID,
@ -1375,7 +1406,7 @@ pm_delete_child(int fd, partition_id partitionID, partition_id childID,
// write changes to disk
PartitionMapWriter writer(fd, 0, partition->size);
// TODO: disk size or 2 * SECTOR_SIZE?
// TODO: The partition is not supposed to be locked at this point!
// TODO: The partition is not supposed to be locked at this point!
status_t error = writer.WriteMBR(map, false);
if (error != B_OK)
return error;
@ -1464,6 +1495,7 @@ ep_validate_resize(partition_data *partition, off_t *size)
return validate_resize(partition, size);
}
// ep_validate_resize_child
bool
ep_validate_resize_child(partition_data *partition, partition_data *child,
@ -1484,6 +1516,7 @@ ep_validate_resize_child(partition_data *partition, partition_data *child,
return true;
}
// ep_validate_move
bool
ep_validate_move(partition_data *partition, off_t *start)
@ -1496,10 +1529,11 @@ ep_validate_move(partition_data *partition, off_t *start)
return true;
}
// ep_validate_move_child
bool
ep_validate_move_child(partition_data *partition, partition_data *child,
off_t *_start)
off_t *_start)
{
TRACE(("intel: ep_validate_move_child\n"));
@ -1518,6 +1552,7 @@ ep_validate_move_child(partition_data *partition, partition_data *child,
return true;
}
// is_type_valid_ep (auxiliary function)
static inline bool
is_type_valid_ep(const char *type)
@ -1528,6 +1563,7 @@ is_type_valid_ep(const char *type)
return (ptype.IsValid() && !ptype.IsEmpty() && !ptype.IsExtended());
}
// ep_validate_set_type
bool
ep_validate_set_type(partition_data *partition, const char *type)
@ -1541,6 +1577,7 @@ ep_validate_set_type(partition_data *partition, const char *type)
return is_type_valid_ep(type);
}
// ep_validate_initialize
bool
ep_validate_initialize(partition_data *partition, char *name,
@ -1558,6 +1595,7 @@ ep_validate_initialize(partition_data *partition, char *name,
return true;
}
// ep_validate_create_child
bool
ep_validate_create_child(partition_data *partition, off_t *_start, off_t *_size,
@ -1599,6 +1637,7 @@ ep_validate_create_child(partition_data *partition, off_t *_start, off_t *_size,
return true;
}
// ep_get_partitionable_spaces
status_t
ep_get_partitionable_spaces(partition_data *partition,
@ -1621,6 +1660,7 @@ ep_get_partitionable_spaces(partition_data *partition,
PTS_OFFSET * SECTOR_SIZE);
}
// ep_get_next_supported_type
status_t
ep_get_next_supported_type(partition_data *partition, int32 *cookie,
@ -1661,6 +1701,7 @@ ep_get_next_supported_type(partition_data *partition, int32 *cookie,
return B_OK;
}
// ep_shadow_changed
status_t
ep_shadow_changed(partition_data *partition, partition_data *child,
@ -1698,7 +1739,7 @@ ep_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
return B_BAD_VALUE;
// validate the new size
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
off_t validatedSize = size;
if (!ep_validate_resize(partition, &validatedSize))
return B_BAD_VALUE;
@ -1706,7 +1747,7 @@ ep_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
// update data stuctures
update_disk_device_job_progress(job, 0.0);
// TODO: partition->size is not supposed to be touched.
// TODO: partition->size is not supposed to be touched.
partition->size = validatedSize;
partition->content_size = validatedSize;
@ -1716,6 +1757,7 @@ ep_resize(int fd, partition_id partitionID, off_t size, disk_job_id job)
return B_OK;
}
// ep_resize_child
status_t
ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
@ -1739,7 +1781,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
return B_BAD_VALUE;
// validate the new size
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
off_t validatedSize = size;
if (!ep_validate_resize_child(partition, child, &validatedSize))
return B_BAD_VALUE;
@ -1751,7 +1793,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
logical->SetSize(validatedSize);
PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here!
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(NULL, logical);
if (error != B_OK) {
// putting into previous state
@ -1773,6 +1815,7 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
return B_OK;
}
// ep_move
status_t
ep_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
@ -1792,7 +1835,7 @@ ep_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
return B_BAD_VALUE;
// validate the new start
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
if (!ep_validate_move(partition, &offset))
return B_BAD_VALUE;
@ -1800,6 +1843,7 @@ ep_move(int fd, partition_id partitionID, off_t offset, disk_job_id job)
return B_OK;
}
// ep_move_child
status_t
ep_move_child(int fd, partition_id partitionID, partition_id childID,
@ -1823,7 +1867,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
if (!logical)
return B_BAD_VALUE;
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
off_t validatedOffset = offset;
if (!ep_validate_move_child(partition, child, &validatedOffset))
return B_BAD_VALUE;
@ -1843,8 +1887,8 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
// partition moving
update_disk_device_job_progress(job, 0.0);
status_t error = B_OK;
// move partition with its header (PTS table)
off_t pts_offset = logical->Offset() - logical->PTSOffset();
// move partition with its header (partition table)
off_t pts_offset = logical->Offset() - logical->PartitionTableOffset();
error = move_partition(fd, child->offset - pts_offset,
validatedOffset - pts_offset, child->size + pts_offset, buffer,
allocated * SECTOR_SIZE, job);
@ -1856,12 +1900,12 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
// updating data structure
child->offset = validatedOffset;
logical->SetOffset(logical->Offset() + diffOffset);
logical->SetPTSOffset(logical->PTSOffset() + diffOffset);
logical->SetPartitionTableOffset(logical->PartitionTableOffset() + diffOffset);
PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: If partition->offset is > prev->offset, then writing
// the previous logical partition table will fail!
// TODO: The partition is not supposed to be locked here!
// TODO: The partition is not supposed to be locked here!
error = writer.WriteLogical(NULL, logical);
if (error != B_OK)
// something went wrong - this is fatal (partition has been moved)
@ -1880,6 +1924,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
return B_OK;
}
// ep_set_type
status_t
ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
@ -1902,7 +1947,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
if (!logical)
return B_BAD_VALUE;
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
if (!ep_validate_set_type(child, type))
return B_BAD_VALUE;
@ -1922,7 +1967,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
logical->SetType(ptype.Type());
PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here!
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(NULL, logical);
if (error != B_OK) {
// something went wrong - putting into previous state
@ -1941,6 +1986,7 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
return B_OK;
}
// ep_initialize
status_t
ep_initialize(int fd, partition_id partitionID, const char *name,
@ -1977,12 +2023,12 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
partition->content_cookie = primary;
// we delete code area in EBR - nothing should be there
partition_table_sector pts;
pts.clear_code_area();
partition_table table;
table.clear_code_area();
PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteExtendedHead(&pts, NULL);
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteExtendedHead(&table, NULL);
if (error != B_OK)
return error;
@ -1992,6 +2038,7 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
return B_OK;
}
// ep_create_child
/*!
childID is used for the return value, but is also an optional input
@ -2021,7 +2068,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
return B_BAD_VALUE;
// validate the offset, size and get index of the new partition
// TODO: The parameter has already been checked and must not be altered!
// TODO: The parameter has already been checked and must not be altered!
off_t validatedOffset = offset;
off_t validatedSize = size;
int32 index = 0;
@ -2047,7 +2094,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
PartitionType ptype;
ptype.SetType(type);
logical->SetPTSOffset(validatedOffset - PTS_OFFSET * SECTOR_SIZE
logical->SetPartitionTableOffset(validatedOffset - PTS_OFFSET * SECTOR_SIZE
- partition->offset);
logical->SetOffset(validatedOffset - partition->offset);
logical->SetSize(validatedSize);
@ -2056,14 +2103,15 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
logical->SetActive(false);
// we delete code area in EBR - nothing should be there
partition_table_sector pts;
pts.clear_code_area();
partition_table table;
table.clear_code_area();
// write changes to disk
PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: wrong offset range, writing prev will fail
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(&pts, logical);
// TODO: The partition is not supposed to be locked here!
status_t error = writer.WriteLogical(&table, logical);
if (error != B_OK) {
// putting into previous state
delete_partition(child->id);
@ -2103,6 +2151,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
return B_OK;
}
// ep_delete_child
status_t
ep_delete_child(int fd, partition_id partitionID, partition_id childID,
@ -2141,7 +2190,7 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
PartitionMapWriter writer(fd, partition->offset, partition->size);
// TODO: Check offset range! Writing "prev/next_logical"?
// Should be parent->offset and parent->size?
// TODO: The partition is not supposed to be locked here!
// TODO: The partition is not supposed to be locked here!
status_t error = prev_logical ? writer.WriteLogical(NULL, prev_logical)
: writer.WriteExtendedHead(NULL, next_logical);
if (error != B_OK)