Refactored a bit -- pulled the partition map parser out. Userland add-on disabled for the time being, due to build problems.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9158 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,22 +1,25 @@
|
|||||||
SubDir OBOS_TOP src add-ons kernel partitioning_systems intel ;
|
SubDir OBOS_TOP src add-ons kernel partitioning_systems intel ;
|
||||||
|
|
||||||
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
||||||
UsePrivateHeaders [ FDirName kernel ] ;
|
UsePrivateHeaders kernel ;
|
||||||
UsePrivateHeaders [ FDirName storage ] ;
|
UsePrivateHeaders shared ;
|
||||||
|
UsePrivateHeaders storage ;
|
||||||
|
|
||||||
KernelAddon intel : kernel partitioning_systems :
|
KernelAddon intel : kernel partitioning_systems :
|
||||||
intel.cpp
|
intel.cpp
|
||||||
PartitionMap.cpp
|
PartitionMap.cpp
|
||||||
|
PartitionMapParser.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
# Also build a userland version
|
# Also build a userland version
|
||||||
# ToDo: it's probably not a good idea to build them into the same directory
|
# ToDo: it's probably not a good idea to build them into the same directory
|
||||||
Addon <partitioning_system>intel : userland partitioning_systems :
|
#Addon <partitioning_system>intel : userland partitioning_systems :
|
||||||
intel.cpp
|
# intel.cpp
|
||||||
PartitionMap.cpp
|
# PartitionMap.cpp
|
||||||
;
|
# PartitionMapParser.cpp
|
||||||
|
#;
|
||||||
|
|
||||||
LinkSharedOSLibs <partitioning_system>intel :
|
#LinkSharedOSLibs <partitioning_system>intel :
|
||||||
libkernelland_emu.so
|
# libkernelland_emu.so
|
||||||
libdisk_device_manager.so
|
# libdisk_device_manager.so
|
||||||
;
|
#;
|
||||||
|
|||||||
@@ -0,0 +1,217 @@
|
|||||||
|
// PartitionMapParser.cpp
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#include "PartitionMap.h"
|
||||||
|
#include "PartitionMapParser.h"
|
||||||
|
|
||||||
|
#define TRACE(x) ;
|
||||||
|
//#define TRACE(x) dprintf x
|
||||||
|
|
||||||
|
// 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, int32 blockSize)
|
||||||
|
: fDeviceFD(deviceFD),
|
||||||
|
fSessionOffset(sessionOffset),
|
||||||
|
fSessionSize(sessionSize),
|
||||||
|
fBlockSize(blockSize),
|
||||||
|
fPTS(NULL),
|
||||||
|
fMap(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
PartitionMapParser::~PartitionMapParser()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse
|
||||||
|
status_t
|
||||||
|
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 (error == B_OK && !fMap->Check(fSessionSize, fBlockSize))
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
fMap = NULL;
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ParsePrimary
|
||||||
|
status_t
|
||||||
|
PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
||||||
|
{
|
||||||
|
status_t error = (pts ? B_OK : B_BAD_VALUE);
|
||||||
|
// check the signature
|
||||||
|
if (error == B_OK && pts->signature != kPartitionTableSectorSignature) {
|
||||||
|
TRACE(("intel: _ParsePrimary(): invalid PTS signature\n"));
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
}
|
||||||
|
// examine the table
|
||||||
|
if (error == B_OK) {
|
||||||
|
for (int32 i = 0; i < 4; i++) {
|
||||||
|
const partition_descriptor *descriptor = &pts->table[i];
|
||||||
|
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
||||||
|
partition->SetTo(descriptor, 0, fBlockSize);
|
||||||
|
// fail, if location is bad
|
||||||
|
if (!partition->CheckLocation(fSessionSize, fBlockSize)) {
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// allocate a PTS buffer
|
||||||
|
if (error == B_OK) {
|
||||||
|
fPTS = new(nothrow) partition_table_sector;
|
||||||
|
if (!fPTS)
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
// parse extended partitions
|
||||||
|
if (error == B_OK) {
|
||||||
|
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||||
|
PrimaryPartition *primary = fMap->PrimaryPartitionAt(i);
|
||||||
|
if (primary->IsExtended())
|
||||||
|
error = _ParseExtended(primary, primary->Offset());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// cleanup
|
||||||
|
if (fPTS) {
|
||||||
|
delete fPTS;
|
||||||
|
fPTS = NULL;
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ParseExtended
|
||||||
|
status_t
|
||||||
|
PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
int32 partitionCount = 0;
|
||||||
|
while (error == B_OK) {
|
||||||
|
// check for cycles
|
||||||
|
if (++partitionCount > kMaxLogicalPartitionCount) {
|
||||||
|
TRACE(("intel: _ParseExtended(): Maximal number of logical "
|
||||||
|
"partitions for extended partition reached. Cycle?\n"));
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
}
|
||||||
|
// read the PTS
|
||||||
|
if (error == B_OK)
|
||||||
|
error = _ReadPTS(offset);
|
||||||
|
// check the signature
|
||||||
|
if (error == B_OK
|
||||||
|
&& fPTS->signature != kPartitionTableSectorSignature) {
|
||||||
|
TRACE(("intel: _ParseExtended(): invalid PTS signature\n"));
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
}
|
||||||
|
// ignore the PTS, if any error occured till now
|
||||||
|
if (error != B_OK) {
|
||||||
|
TRACE(("intel: _ParseExtended(): ignoring this PTS\n"));
|
||||||
|
error = B_OK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// examine the table
|
||||||
|
LogicalPartition extended;
|
||||||
|
LogicalPartition nonExtended;
|
||||||
|
if (error == B_OK) {
|
||||||
|
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
||||||
|
const partition_descriptor *descriptor = &fPTS->table[i];
|
||||||
|
LogicalPartition *partition = NULL;
|
||||||
|
if (!descriptor->is_empty()) {
|
||||||
|
if (descriptor->is_extended()) {
|
||||||
|
if (extended.IsEmpty()) {
|
||||||
|
extended.SetTo(descriptor, offset, fBlockSize,
|
||||||
|
primary);
|
||||||
|
partition = &extended;
|
||||||
|
} else {
|
||||||
|
// only one extended partition allowed
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
TRACE(("intel: _ParseExtended(): "
|
||||||
|
"only one extended partition allowed\n"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (nonExtended.IsEmpty()) {
|
||||||
|
nonExtended.SetTo(descriptor, offset, fBlockSize,
|
||||||
|
primary);
|
||||||
|
partition = &nonExtended;
|
||||||
|
} else {
|
||||||
|
// only one non-extended partition allowed
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
TRACE(("intel: _ParseExtended(): only one "
|
||||||
|
"non-extended partition allowed\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// check the partition's location
|
||||||
|
if (partition && !partition->CheckLocation(fSessionSize,
|
||||||
|
fBlockSize)) {
|
||||||
|
error = B_BAD_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// add non-extended partition to list
|
||||||
|
if (error == B_OK && !nonExtended.IsEmpty()) {
|
||||||
|
LogicalPartition *partition
|
||||||
|
= new(nothrow) LogicalPartition(nonExtended);
|
||||||
|
if (partition)
|
||||||
|
primary->AddLogicalPartition(partition);
|
||||||
|
else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
// prepare to parse next extended partition
|
||||||
|
if (error == B_OK && !extended.IsEmpty())
|
||||||
|
offset = extended.Offset();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// _ReadPTS
|
||||||
|
status_t
|
||||||
|
PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
if (!pts)
|
||||||
|
pts = fPTS;
|
||||||
|
int32 toRead = sizeof(partition_table_sector);
|
||||||
|
// check the offset
|
||||||
|
if (offset < 0 || offset + toRead > fSessionSize) {
|
||||||
|
error = B_BAD_VALUE;
|
||||||
|
TRACE(("intel: _ReadPTS(): bad offset: %Ld\n", offset));
|
||||||
|
// read
|
||||||
|
} else if (read_pos(fDeviceFD, fSessionOffset + offset, pts, toRead)
|
||||||
|
!= toRead) {
|
||||||
|
#ifndef _BOOT_MODE
|
||||||
|
error = errno;
|
||||||
|
if (error == B_OK)
|
||||||
|
error = B_IO_ERROR;
|
||||||
|
#else
|
||||||
|
error = B_IO_ERROR;
|
||||||
|
#endif
|
||||||
|
TRACE(("intel: _ReadPTS(): reading the PTS failed: %s\n",
|
||||||
|
strerror(error)));
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
// PartitionMapParser.h
|
||||||
|
|
||||||
|
#ifndef PARTITION_MAP_PARSER_H
|
||||||
|
#define PARTITION_MAP_PARSER_H
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
class Partition;
|
||||||
|
class PartitionMap;
|
||||||
|
class PrimaryPartition;
|
||||||
|
struct partition_table_sector;
|
||||||
|
|
||||||
|
class PartitionMapParser {
|
||||||
|
public:
|
||||||
|
PartitionMapParser(int deviceFD, off_t sessionOffset, off_t sessionSize,
|
||||||
|
int32 blockSize);
|
||||||
|
~PartitionMapParser();
|
||||||
|
|
||||||
|
status_t Parse(const uint8 *block, PartitionMap *map);
|
||||||
|
|
||||||
|
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:
|
||||||
|
int fDeviceFD;
|
||||||
|
off_t fSessionOffset;
|
||||||
|
off_t fSessionSize;
|
||||||
|
int32 fBlockSize;
|
||||||
|
partition_table_sector *fPTS; // while parsing
|
||||||
|
PartitionMap *fMap; //
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PARTITION_MAP_PARSER_H
|
||||||
@@ -16,18 +16,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
|
#include <AutoDeleter.h>
|
||||||
#include <ddm_modules.h>
|
#include <ddm_modules.h>
|
||||||
#ifndef _BOOT_MODE
|
#ifndef _BOOT_MODE
|
||||||
# include <DiskDeviceTypes.h>
|
# include <DiskDeviceTypes.h>
|
||||||
#else
|
#else
|
||||||
# include <boot/partitions.h>
|
# include <boot/partitions.h>
|
||||||
|
//# include "DiskDeviceUtils.h"
|
||||||
#endif
|
#endif
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
#include "PartitionMap.h"
|
#include "PartitionMap.h"
|
||||||
|
#include "PartitionMapParser.h"
|
||||||
|
|
||||||
#define TRACE(x) ;
|
#define TRACE(x) ;
|
||||||
//#define TRACE(x) dprintf x
|
//#define TRACE(x) dprintf x
|
||||||
@@ -40,251 +42,6 @@
|
|||||||
#define INTEL_PARTITION_NAME "Intel Partition Map"
|
#define INTEL_PARTITION_NAME "Intel Partition Map"
|
||||||
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
|
#define INTEL_EXTENDED_PARTITION_NAME "Intel Extended Partition"
|
||||||
|
|
||||||
// Maximal number of logical partitions per extended partition we allow.
|
|
||||||
static const int32 kMaxLogicalPartitionCount = 128;
|
|
||||||
|
|
||||||
|
|
||||||
// AutoDeleter
|
|
||||||
|
|
||||||
template<typename C>
|
|
||||||
class AutoDeleter {
|
|
||||||
public:
|
|
||||||
AutoDeleter(C *object) : fObject(object) {}
|
|
||||||
~AutoDeleter() { delete fObject; }
|
|
||||||
void SetObject(C *object) { fObject = object; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
C *fObject;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// PartitionMapParser
|
|
||||||
|
|
||||||
class PartitionMapParser {
|
|
||||||
public:
|
|
||||||
PartitionMapParser(int deviceFD, off_t sessionOffset, off_t sessionSize,
|
|
||||||
int32 blockSize);
|
|
||||||
~PartitionMapParser();
|
|
||||||
|
|
||||||
status_t Parse(const uint8 *block, PartitionMap *map);
|
|
||||||
|
|
||||||
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:
|
|
||||||
int fDeviceFD;
|
|
||||||
off_t fSessionOffset;
|
|
||||||
off_t fSessionSize;
|
|
||||||
int32 fBlockSize;
|
|
||||||
partition_table_sector *fPTS; // while parsing
|
|
||||||
PartitionMap *fMap; //
|
|
||||||
};
|
|
||||||
|
|
||||||
// constructor
|
|
||||||
PartitionMapParser::PartitionMapParser(int deviceFD, off_t sessionOffset,
|
|
||||||
off_t sessionSize, int32 blockSize)
|
|
||||||
: fDeviceFD(deviceFD),
|
|
||||||
fSessionOffset(sessionOffset),
|
|
||||||
fSessionSize(sessionSize),
|
|
||||||
fBlockSize(blockSize),
|
|
||||||
fPTS(NULL),
|
|
||||||
fMap(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
PartitionMapParser::~PartitionMapParser()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse
|
|
||||||
status_t
|
|
||||||
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 (error == B_OK && !fMap->Check(fSessionSize, fBlockSize))
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
fMap = NULL;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _ParsePrimary
|
|
||||||
status_t
|
|
||||||
PartitionMapParser::_ParsePrimary(const partition_table_sector *pts)
|
|
||||||
{
|
|
||||||
status_t error = (pts ? B_OK : B_BAD_VALUE);
|
|
||||||
// check the signature
|
|
||||||
if (error == B_OK && pts->signature != kPartitionTableSectorSignature) {
|
|
||||||
TRACE(("intel: _ParsePrimary(): invalid PTS signature\n"));
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
}
|
|
||||||
// examine the table
|
|
||||||
if (error == B_OK) {
|
|
||||||
for (int32 i = 0; i < 4; i++) {
|
|
||||||
const partition_descriptor *descriptor = &pts->table[i];
|
|
||||||
PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
|
||||||
partition->SetTo(descriptor, 0, fBlockSize);
|
|
||||||
// fail, if location is bad
|
|
||||||
if (!partition->CheckLocation(fSessionSize, fBlockSize)) {
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// allocate a PTS buffer
|
|
||||||
if (error == B_OK) {
|
|
||||||
fPTS = new(nothrow) partition_table_sector;
|
|
||||||
if (!fPTS)
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// parse extended partitions
|
|
||||||
if (error == B_OK) {
|
|
||||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
|
||||||
PrimaryPartition *primary = fMap->PrimaryPartitionAt(i);
|
|
||||||
if (primary->IsExtended())
|
|
||||||
error = _ParseExtended(primary, primary->Offset());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// cleanup
|
|
||||||
if (fPTS) {
|
|
||||||
delete fPTS;
|
|
||||||
fPTS = NULL;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _ParseExtended
|
|
||||||
status_t
|
|
||||||
PartitionMapParser::_ParseExtended(PrimaryPartition *primary, off_t offset)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
int32 partitionCount = 0;
|
|
||||||
while (error == B_OK) {
|
|
||||||
// check for cycles
|
|
||||||
if (++partitionCount > kMaxLogicalPartitionCount) {
|
|
||||||
TRACE(("intel: _ParseExtended(): Maximal number of logical "
|
|
||||||
"partitions for extended partition reached. Cycle?\n"));
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
}
|
|
||||||
// read the PTS
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _ReadPTS(offset);
|
|
||||||
// check the signature
|
|
||||||
if (error == B_OK
|
|
||||||
&& fPTS->signature != kPartitionTableSectorSignature) {
|
|
||||||
TRACE(("intel: _ParseExtended(): invalid PTS signature\n"));
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
}
|
|
||||||
// ignore the PTS, if any error occured till now
|
|
||||||
if (error != B_OK) {
|
|
||||||
TRACE(("intel: _ParseExtended(): ignoring this PTS\n"));
|
|
||||||
error = B_OK;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// examine the table
|
|
||||||
LogicalPartition extended;
|
|
||||||
LogicalPartition nonExtended;
|
|
||||||
if (error == B_OK) {
|
|
||||||
for (int32 i = 0; error == B_OK && i < 4; i++) {
|
|
||||||
const partition_descriptor *descriptor = &fPTS->table[i];
|
|
||||||
LogicalPartition *partition = NULL;
|
|
||||||
if (!descriptor->is_empty()) {
|
|
||||||
if (descriptor->is_extended()) {
|
|
||||||
if (extended.IsEmpty()) {
|
|
||||||
extended.SetTo(descriptor, offset, fBlockSize,
|
|
||||||
primary);
|
|
||||||
partition = &extended;
|
|
||||||
} else {
|
|
||||||
// only one extended partition allowed
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
TRACE(("intel: _ParseExtended(): "
|
|
||||||
"only one extended partition allowed\n"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (nonExtended.IsEmpty()) {
|
|
||||||
nonExtended.SetTo(descriptor, offset, fBlockSize,
|
|
||||||
primary);
|
|
||||||
partition = &nonExtended;
|
|
||||||
} else {
|
|
||||||
// only one non-extended partition allowed
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
TRACE(("intel: _ParseExtended(): only one "
|
|
||||||
"non-extended partition allowed\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check the partition's location
|
|
||||||
if (partition && !partition->CheckLocation(fSessionSize,
|
|
||||||
fBlockSize)) {
|
|
||||||
error = B_BAD_DATA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// add non-extended partition to list
|
|
||||||
if (error == B_OK && !nonExtended.IsEmpty()) {
|
|
||||||
LogicalPartition *partition
|
|
||||||
= new(nothrow) LogicalPartition(nonExtended);
|
|
||||||
if (partition)
|
|
||||||
primary->AddLogicalPartition(partition);
|
|
||||||
else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// prepare to parse next extended partition
|
|
||||||
if (error == B_OK && !extended.IsEmpty())
|
|
||||||
offset = extended.Offset();
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// _ReadPTS
|
|
||||||
status_t
|
|
||||||
PartitionMapParser::_ReadPTS(off_t offset, partition_table_sector *pts)
|
|
||||||
{
|
|
||||||
status_t error = B_OK;
|
|
||||||
if (!pts)
|
|
||||||
pts = fPTS;
|
|
||||||
int32 toRead = sizeof(partition_table_sector);
|
|
||||||
// check the offset
|
|
||||||
if (offset < 0 || offset + toRead > fSessionSize) {
|
|
||||||
error = B_BAD_VALUE;
|
|
||||||
TRACE(("intel: _ReadPTS(): bad offset: %Ld\n", offset));
|
|
||||||
// read
|
|
||||||
} else if (read_pos(fDeviceFD, fSessionOffset + offset, pts, toRead)
|
|
||||||
!= toRead) {
|
|
||||||
#ifndef _BOOT_MODE
|
|
||||||
error = errno;
|
|
||||||
if (error == B_OK)
|
|
||||||
error = B_IO_ERROR;
|
|
||||||
#else
|
|
||||||
error = B_IO_ERROR;
|
|
||||||
#endif
|
|
||||||
TRACE(("intel: _ReadPTS(): reading the PTS failed: %s\n",
|
|
||||||
strerror(error)));
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// intel partition map module
|
// intel partition map module
|
||||||
|
|
||||||
@@ -308,13 +65,18 @@ static bool pm_supports_resizing_child(partition_data *partition,
|
|||||||
|
|
||||||
static bool pm_validate_resize_child(partition_data *partition,
|
static bool pm_validate_resize_child(partition_data *partition,
|
||||||
partition_data *child, off_t *size);
|
partition_data *child, off_t *size);
|
||||||
|
|
||||||
|
// writing
|
||||||
|
static status_t pm_resize_child(int fd, partition_id partition, off_t size,
|
||||||
|
disk_job_id job);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
partition_module_info gIntelPartitionMapModule = {
|
partition_module_info gIntelPartitionMapModule =
|
||||||
#else
|
#else
|
||||||
static partition_module_info intel_partition_map_module = {
|
static partition_module_info intel_partition_map_module =
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
{
|
{
|
||||||
INTEL_PARTITION_MODULE_NAME,
|
INTEL_PARTITION_MODULE_NAME,
|
||||||
0,
|
0,
|
||||||
@@ -369,7 +131,7 @@ static partition_module_info intel_partition_map_module = {
|
|||||||
// writing
|
// writing
|
||||||
NULL, // repair
|
NULL, // repair
|
||||||
NULL, // resize
|
NULL, // resize
|
||||||
NULL, // resize_child
|
pm_resize_child, // resize_child
|
||||||
NULL, // move
|
NULL, // move
|
||||||
NULL, // move_child
|
NULL, // move_child
|
||||||
NULL, // set_name
|
NULL, // set_name
|
||||||
@@ -402,10 +164,11 @@ static void ep_free_partition_cookie(partition_data *partition);
|
|||||||
static void ep_free_partition_content_cookie(partition_data *partition);
|
static void ep_free_partition_content_cookie(partition_data *partition);
|
||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
partition_module_info gIntelExtendedPartitionModule = {
|
partition_module_info gIntelExtendedPartitionModule =
|
||||||
#else
|
#else
|
||||||
static partition_module_info intel_extended_partition_module = {
|
static partition_module_info intel_extended_partition_module =
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
{
|
{
|
||||||
INTEL_EXTENDED_PARTITION_MODULE_NAME,
|
INTEL_EXTENDED_PARTITION_MODULE_NAME,
|
||||||
0,
|
0,
|
||||||
@@ -548,7 +311,7 @@ static
|
|||||||
status_t
|
status_t
|
||||||
pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
pm_scan_partition(int fd, partition_data *partition, void *cookie)
|
||||||
{
|
{
|
||||||
AutoDeleter<PartitionMap> deleter((PartitionMap*)cookie);
|
ObjectDeleter<PartitionMap> deleter((PartitionMap*)cookie);
|
||||||
// check parameters
|
// check parameters
|
||||||
if (fd < 0 || !partition || !cookie)
|
if (fd < 0 || !partition || !cookie)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -603,7 +366,7 @@ TRACE(("Creating child at index %ld failed\n", index - 1));
|
|||||||
}
|
}
|
||||||
// keep map on success or cleanup on error
|
// keep map on success or cleanup on error
|
||||||
if (error == B_OK) {
|
if (error == B_OK) {
|
||||||
deleter.SetObject(NULL);
|
deleter.Detach();
|
||||||
} else {
|
} else {
|
||||||
partition->content_cookie = NULL;
|
partition->content_cookie = NULL;
|
||||||
for (int32 i = 0; i < partition->child_count; i++) {
|
for (int32 i = 0; i < partition->child_count; i++) {
|
||||||
@@ -693,6 +456,41 @@ pm_validate_resize_child(partition_data *partition, partition_data *child,
|
|||||||
*size = *size / partition->block_size * partition->block_size;
|
*size = *size / partition->block_size * partition->block_size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pm_resize_child
|
||||||
|
static
|
||||||
|
status_t
|
||||||
|
pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
disk_device_data *device = read_lock_disk_device(partitionID);
|
||||||
|
if (!device)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
DeviceStructWriteLocker locker(device, true);
|
||||||
|
// get partition and child and out partition map structure
|
||||||
|
partition_data *partition = get_parent_partition(partitionID);
|
||||||
|
partition_data *child = get_partition(partitionID);
|
||||||
|
if (!partition || !child)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
PartitionMap *map = (PartitionMap*)partition->content_cookie;
|
||||||
|
PrimaryPartition *primary = child->cookie;
|
||||||
|
if (!map || !primary)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
// validate the new size
|
||||||
|
off_t validatedSize = size;
|
||||||
|
if (!pm_validate_resize_child(partition, child, validatedSize)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (child->size == validatedSize)
|
||||||
|
return B_OK;
|
||||||
|
// write the changes to disk
|
||||||
|
primary->SetSize(validatedSize);
|
||||||
|
// TODO: Write...
|
||||||
|
// TODO: PartitionMapParser into separate file,
|
||||||
|
// implement PartitionMapWriter
|
||||||
|
*/
|
||||||
|
set_disk_device_job_error_message(job, "Resize not implemented yet.");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
#endif // _BOOT_MODE
|
#endif // _BOOT_MODE
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user