Beginnings of a userland intel disk system add-on.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22542 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
260bb9a2a1
commit
91c21ff4d6
@ -2,6 +2,7 @@ SubDir HAIKU_TOP src add-ons ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons accelerants ;
|
||||
SubInclude HAIKU_TOP src add-ons decorators ;
|
||||
SubInclude HAIKU_TOP src add-ons disk_systems ;
|
||||
SubInclude HAIKU_TOP src add-ons input_server ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel ;
|
||||
SubInclude HAIKU_TOP src add-ons mail_daemon ;
|
||||
|
109
src/add-ons/disk_systems/intel/ExtendedPartitionAddOn.cpp
Normal file
109
src/add-ons/disk_systems/intel/ExtendedPartitionAddOn.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "ExtendedPartitionAddOn.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <DiskDeviceTypes.h>
|
||||
#include <MutablePartition.h>
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
// #pragma mark - ExtendedPartitionAddOn
|
||||
|
||||
|
||||
// constructor
|
||||
ExtendedPartitionAddOn::ExtendedPartitionAddOn()
|
||||
: BDiskSystemAddOn(kPartitionTypeIntel, 0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
ExtendedPartitionAddOn::~ExtendedPartitionAddOn()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// CreatePartitionHandle
|
||||
status_t
|
||||
ExtendedPartitionAddOn::CreatePartitionHandle(BMutablePartition* partition,
|
||||
BPartitionHandle** _handle)
|
||||
{
|
||||
ExtendedPartitionHandle* handle
|
||||
= new(nothrow) ExtendedPartitionHandle(partition);
|
||||
if (!handle)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = handle->Init();
|
||||
if (error != B_OK) {
|
||||
delete handle;
|
||||
return error;
|
||||
}
|
||||
|
||||
*_handle = handle;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - ExtendedPartitionHandle
|
||||
|
||||
|
||||
// constructor
|
||||
ExtendedPartitionHandle::ExtendedPartitionHandle(BMutablePartition* partition)
|
||||
: BPartitionHandle(partition)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
ExtendedPartitionHandle::~ExtendedPartitionHandle()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Init
|
||||
status_t
|
||||
ExtendedPartitionHandle::Init()
|
||||
{
|
||||
// initialize the extended partition from the mutable partition
|
||||
|
||||
BMutablePartition* partition = Partition();
|
||||
|
||||
// our parent has already set the child cookie to the primary partition.
|
||||
fPrimaryPartition = (PrimaryPartition*)partition->ChildCookie();
|
||||
if (!fPrimaryPartition)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (!fPrimaryPartition->IsExtended())
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// init the child partitions
|
||||
int32 count = partition->CountChildren();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BMutablePartition* child = partition->ChildAt(i);
|
||||
PartitionType type;
|
||||
if (!type.SetType(child->Type()))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: Get these from the parameters.
|
||||
bool active = false;
|
||||
off_t ptsOffset = 0;
|
||||
|
||||
LogicalPartition* logical = new(nothrow) LogicalPartition;
|
||||
if (!logical)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
logical->SetTo(child->Offset(), child->Size(), type.Type(), active,
|
||||
ptsOffset, fPrimaryPartition);
|
||||
|
||||
child->SetChildCookie(logical);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
38
src/add-ons/disk_systems/intel/ExtendedPartitionAddOn.h
Normal file
38
src/add-ons/disk_systems/intel/ExtendedPartitionAddOn.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _EXTENDED_PARTITION_ADD_ON_H
|
||||
#define _EXTENDED_PARTITION_ADD_ON_H
|
||||
|
||||
#include <DiskSystemAddOn.h>
|
||||
|
||||
#include "PartitionMap.h"
|
||||
|
||||
|
||||
class ExtendedPartitionAddOn : public BDiskSystemAddOn {
|
||||
public:
|
||||
ExtendedPartitionAddOn();
|
||||
virtual ~ExtendedPartitionAddOn();
|
||||
|
||||
virtual status_t CreatePartitionHandle(
|
||||
BMutablePartition* partition,
|
||||
BPartitionHandle** handle);
|
||||
|
||||
};
|
||||
|
||||
|
||||
class ExtendedPartitionHandle : public BPartitionHandle {
|
||||
public:
|
||||
ExtendedPartitionHandle(
|
||||
BMutablePartition* partition);
|
||||
virtual ~ExtendedPartitionHandle();
|
||||
|
||||
status_t Init();
|
||||
|
||||
private:
|
||||
PrimaryPartition* fPrimaryPartition;
|
||||
};
|
||||
|
||||
|
||||
#endif // _EXTENDED_PARTITION_ADD_ON_H
|
43
src/add-ons/disk_systems/intel/IntelDiskSystem.cpp
Normal file
43
src/add-ons/disk_systems/intel/IntelDiskSystem.cpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <List.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include "ExtendedPartitionAddOn.h"
|
||||
#include "PartitionMapAddOn.h"
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
// get_disk_system_add_ons
|
||||
status_t
|
||||
get_disk_system_add_ons(BList* addOns)
|
||||
{
|
||||
PartitionMapAddOn* partitionMapAddOn = new(nothrow) PartitionMapAddOn;
|
||||
ExtendedPartitionAddOn* extendedPartitionAddOn
|
||||
= new(nothrow) ExtendedPartitionAddOn;
|
||||
|
||||
ObjectDeleter<PartitionMapAddOn> mapAddOnDeleter(partitionMapAddOn);
|
||||
ObjectDeleter<ExtendedPartitionAddOn> extendedAddOnDeleter(
|
||||
extendedPartitionAddOn);
|
||||
|
||||
BList list;
|
||||
if (!partitionMapAddOn || !extendedPartitionAddOn
|
||||
|| !list.AddItem(partitionMapAddOn)
|
||||
|| !list.AddItem(extendedPartitionAddOn)
|
||||
|| !addOns->AddList(&list)) {
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
mapAddOnDeleter.Detach();
|
||||
extendedAddOnDeleter.Detach();
|
||||
|
||||
return B_OK;
|
||||
}
|
18
src/add-ons/disk_systems/intel/IntelDiskSystem.h
Normal file
18
src/add-ons/disk_systems/intel/IntelDiskSystem.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _INTEL_DISK_SYSTEM_H
|
||||
#define _INTEL_DISK_SYSTEM_H
|
||||
|
||||
#include "PartitionMap.h"
|
||||
|
||||
|
||||
static inline off_t
|
||||
sector_align(off_t offset)
|
||||
{
|
||||
return offset / SECTOR_SIZE * SECTOR_SIZE;
|
||||
}
|
||||
|
||||
|
||||
#endif // _INTEL_DISK_SYSTEM_H
|
24
src/add-ons/disk_systems/intel/Jamfile
Normal file
24
src/add-ons/disk_systems/intel/Jamfile
Normal file
@ -0,0 +1,24 @@
|
||||
SubDir HAIKU_TOP src add-ons disk_systems intel ;
|
||||
|
||||
UsePrivateHeaders shared ;
|
||||
UsePrivateHeaders storage ;
|
||||
|
||||
SEARCH_SOURCE
|
||||
+= [ FDirName $(HAIKU_TOP) src add-ons kernel partitioning_systems intel ] ;
|
||||
|
||||
{
|
||||
local defines = [ FDefines _USER_MODE ] ;
|
||||
SubDirCcFlags $(defines) ;
|
||||
SubDirC++Flags $(defines) ;
|
||||
}
|
||||
|
||||
Addon <disk_system>intel :
|
||||
IntelDiskSystem.cpp
|
||||
ExtendedPartitionAddOn.cpp
|
||||
PartitionMapAddOn.cpp
|
||||
|
||||
# kernel sources
|
||||
PartitionMap.cpp
|
||||
|
||||
: be
|
||||
;
|
483
src/add-ons/disk_systems/intel/PartitionMapAddOn.cpp
Normal file
483
src/add-ons/disk_systems/intel/PartitionMapAddOn.cpp
Normal file
@ -0,0 +1,483 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
#include "PartitionMapAddOn.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <DiskDeviceTypes.h>
|
||||
#include <MutablePartition.h>
|
||||
#include <PartitioningInfo.h>
|
||||
|
||||
#include <AutoDeleter.h>
|
||||
|
||||
#include "IntelDiskSystem.h"
|
||||
|
||||
|
||||
using std::nothrow;
|
||||
|
||||
|
||||
static const uint32 kDiskSystemFlags =
|
||||
0
|
||||
// | B_DISK_SYSTEM_SUPPORTS_CHECKING
|
||||
// | B_DISK_SYSTEM_SUPPORTS_REPAIRING
|
||||
| B_DISK_SYSTEM_SUPPORTS_RESIZING
|
||||
| B_DISK_SYSTEM_SUPPORTS_MOVING
|
||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME
|
||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
|
||||
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
||||
// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
||||
|
||||
| B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
||||
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
|
||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_NAME
|
||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
|
||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_PARAMETERS
|
||||
| B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD
|
||||
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD
|
||||
// | B_DISK_SYSTEM_SUPPORTS_NAME
|
||||
;
|
||||
|
||||
|
||||
// #pragma mark - PartitionMapAddOn
|
||||
|
||||
|
||||
// constructor
|
||||
PartitionMapAddOn::PartitionMapAddOn()
|
||||
: BDiskSystemAddOn(kPartitionTypeIntel, kDiskSystemFlags)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
PartitionMapAddOn::~PartitionMapAddOn()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// CreatePartitionHandle
|
||||
status_t
|
||||
PartitionMapAddOn::CreatePartitionHandle(BMutablePartition* partition,
|
||||
BPartitionHandle** _handle)
|
||||
{
|
||||
PartitionMapHandle* handle = new(nothrow) PartitionMapHandle(partition);
|
||||
if (!handle)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = handle->Init();
|
||||
if (error != B_OK) {
|
||||
delete handle;
|
||||
return error;
|
||||
}
|
||||
|
||||
*_handle = handle;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// CanInitialize
|
||||
bool
|
||||
PartitionMapAddOn::CanInitialize(const BMutablePartition* partition)
|
||||
{
|
||||
// If it's big enough, we can initialize it.
|
||||
return partition->Size() >= 2 * SECTOR_SIZE;
|
||||
}
|
||||
|
||||
|
||||
// GetInitializationParameterEditor
|
||||
status_t
|
||||
PartitionMapAddOn::GetInitializationParameterEditor(
|
||||
const BMutablePartition* partition, BDiskDeviceParameterEditor** editor)
|
||||
{
|
||||
// Nothing to edit, really.
|
||||
*editor = NULL;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ValidateInitialize
|
||||
status_t
|
||||
PartitionMapAddOn::ValidateInitialize(const BMutablePartition* partition,
|
||||
BString* name, const char* parameters)
|
||||
{
|
||||
if (!CanInitialize(partition)
|
||||
|| parameters != NULL && strlen(parameters) > 0) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// we don't support a content name
|
||||
if (name != NULL)
|
||||
name->Truncate(0);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// Initialize
|
||||
status_t
|
||||
PartitionMapAddOn::Initialize(BMutablePartition* partition, const char* name,
|
||||
const char* parameters, BPartitionHandle** _handle)
|
||||
{
|
||||
if (!CanInitialize(partition)
|
||||
|| name != NULL && strlen(name) > 0
|
||||
|| parameters != NULL && strlen(parameters) > 0) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// create the handle
|
||||
PartitionMapHandle* handle = new(nothrow) PartitionMapHandle(partition);
|
||||
if (!handle)
|
||||
return B_NO_MEMORY;
|
||||
ObjectDeleter<PartitionMapHandle> handleDeleter(handle);
|
||||
|
||||
// init the partition
|
||||
status_t error = partition->SetContentType(Name());
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// TODO: The content type could as well be set by the caller.
|
||||
|
||||
partition->SetContentName(NULL);
|
||||
partition->SetContentParameters(NULL);
|
||||
partition->SetBlockSize(SECTOR_SIZE);
|
||||
partition->SetContentSize(partition->Size() / SECTOR_SIZE * SECTOR_SIZE);
|
||||
|
||||
*_handle = handleDeleter.Detach();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - PartitionMapHandle
|
||||
|
||||
|
||||
// constructor
|
||||
PartitionMapHandle::PartitionMapHandle(BMutablePartition* partition)
|
||||
: BPartitionHandle(partition)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
PartitionMapHandle::~PartitionMapHandle()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Init
|
||||
status_t
|
||||
PartitionMapHandle::Init()
|
||||
{
|
||||
// initialize the partition map from the mutable partition
|
||||
|
||||
BMutablePartition* partition = Partition();
|
||||
|
||||
int32 count = partition->CountChildren();
|
||||
if (count > 4)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
int32 extendedCount = 0;
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
BMutablePartition* child = partition->ChildAt(i);
|
||||
PartitionType type;
|
||||
if (!type.SetType(child->Type()))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// only one extended partition is allowed
|
||||
if (type.IsExtended()) {
|
||||
if (++extendedCount > 1)
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// TODO: Get these from the parameters.
|
||||
int32 index = i;
|
||||
bool active = false;
|
||||
|
||||
PrimaryPartition* primary = fPartitionMap.PrimaryPartitionAt(index);
|
||||
primary->SetTo(child->Offset(), child->Size(), type.Type(), active);
|
||||
|
||||
child->SetChildCookie(primary);
|
||||
}
|
||||
|
||||
// The extended partition (if any) is initialized by
|
||||
// ExtendedPartitionHandle::Init().
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// SupportedOperations
|
||||
uint32
|
||||
PartitionMapHandle::SupportedOperations(uint32 mask)
|
||||
{
|
||||
BMutablePartition* partition = Partition();
|
||||
|
||||
uint32 flags = B_DISK_SYSTEM_SUPPORTS_RESIZING
|
||||
| B_DISK_SYSTEM_SUPPORTS_MOVING
|
||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
|
||||
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING;
|
||||
|
||||
// creating child
|
||||
if (mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) {
|
||||
BPartitioningInfo info;
|
||||
if (partition->CountChildren() < 4
|
||||
&& GetPartitioningInfo(&info) == B_OK
|
||||
&& info.CountPartitionableSpaces() > 1) {
|
||||
flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
// SupportedChildOperations
|
||||
uint32
|
||||
PartitionMapHandle::SupportedChildOperations(const BMutablePartition* child,
|
||||
uint32 mask)
|
||||
{
|
||||
return B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
||||
| B_DISK_SYSTEM_SUPPORTS_MOVING_CHILD
|
||||
| B_DISK_SYSTEM_SUPPORTS_SETTING_TYPE
|
||||
| B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD;
|
||||
}
|
||||
|
||||
|
||||
// GetPartitioningInfo
|
||||
status_t
|
||||
PartitionMapHandle::GetPartitioningInfo(BPartitioningInfo* info)
|
||||
{
|
||||
// init to the full size (minus the first sector)
|
||||
off_t size = Partition()->ContentSize();
|
||||
status_t error = info->SetTo(SECTOR_SIZE, size - SECTOR_SIZE);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// exclude the space of the existing partitions
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
PrimaryPartition* primary = fPartitionMap.PrimaryPartitionAt(i);
|
||||
if (!primary->IsEmpty()) {
|
||||
error = info->ExcludeOccupiedSpace(primary->Offset(),
|
||||
primary->Size());
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// GetChildCreationParameterEditor
|
||||
status_t
|
||||
PartitionMapHandle::GetChildCreationParameterEditor(const char* type,
|
||||
BDiskDeviceParameterEditor** editor)
|
||||
{
|
||||
// TODO: We actually need an editor here.
|
||||
*editor = NULL;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// ValidateCreateChild
|
||||
status_t
|
||||
PartitionMapHandle::ValidateCreateChild(off_t* _offset, off_t* _size,
|
||||
const char* typeString, BString* name, const char* parameters)
|
||||
{
|
||||
// check type
|
||||
PartitionType type;
|
||||
if (!type.SetType(typeString) || type.IsEmpty())
|
||||
return B_BAD_VALUE;
|
||||
if (type.IsExtended() && fPartitionMap.ExtendedPartitionIndex() >= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check name
|
||||
if (name)
|
||||
name->Truncate(0);
|
||||
|
||||
// check parameters
|
||||
// TODO:...
|
||||
|
||||
// do we have a spare primary partition?
|
||||
if (fPartitionMap.CountNonEmptyPrimaryPartitions() == 4)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check the free space situation
|
||||
BPartitioningInfo info;
|
||||
status_t error = GetPartitioningInfo(&info);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// any space in the partition at all?
|
||||
int32 spacesCount = info.CountPartitionableSpaces();
|
||||
if (spacesCount == 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check offset and size
|
||||
off_t offset = sector_align(*_offset);
|
||||
off_t size = sector_align(*_size);
|
||||
// TODO: Rather round size up?
|
||||
off_t end = offset + size;
|
||||
|
||||
// get the first partitionable space the requested interval intersects with
|
||||
int32 spaceIndex = -1;
|
||||
int32 closestSpaceIndex = -1;
|
||||
off_t closestSpaceDistance = 0;
|
||||
for (int32 i = 0; i < spacesCount; i++) {
|
||||
off_t spaceOffset, spaceSize;
|
||||
info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
||||
off_t spaceEnd = spaceOffset + spaceSize;
|
||||
|
||||
if (spaceOffset >= offset && spaceOffset < end
|
||||
|| offset >= spaceOffset && offset < spaceEnd) {
|
||||
spaceIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
off_t distance;
|
||||
if (offset < spaceOffset)
|
||||
distance = spaceOffset - end;
|
||||
else
|
||||
distance = spaceEnd - offset;
|
||||
|
||||
if (closestSpaceIndex == -1 || distance < closestSpaceDistance) {
|
||||
closestSpaceIndex = i;
|
||||
closestSpaceDistance = distance;
|
||||
}
|
||||
}
|
||||
|
||||
// get the space we found
|
||||
off_t spaceOffset, spaceSize;
|
||||
info.GetPartitionableSpaceAt(
|
||||
spaceIndex >= 0 ? spaceIndex : closestSpaceIndex, &spaceOffset,
|
||||
&spaceSize);
|
||||
off_t spaceEnd = spaceOffset + spaceSize;
|
||||
|
||||
// If the requested intervald doesn't intersect with any space yet, move
|
||||
// it, so that it does.
|
||||
if (spaceIndex < 0) {
|
||||
spaceIndex = closestSpaceIndex;
|
||||
if (offset < spaceOffset) {
|
||||
offset = spaceOffset;
|
||||
end = offset + size;
|
||||
} else {
|
||||
end = spaceEnd;
|
||||
offset = end - size;
|
||||
}
|
||||
}
|
||||
|
||||
// move/shrink the interval, so that it fully lies within the space
|
||||
if (offset < spaceOffset) {
|
||||
offset = spaceOffset;
|
||||
end = offset + size;
|
||||
if (end > spaceEnd) {
|
||||
end = spaceEnd;
|
||||
size = end - offset;
|
||||
}
|
||||
} else if (end > spaceEnd) {
|
||||
end = spaceEnd;
|
||||
offset = end - size;
|
||||
if (offset < spaceOffset) {
|
||||
offset = spaceOffset;
|
||||
size = end - offset;
|
||||
}
|
||||
}
|
||||
|
||||
*_offset = offset;
|
||||
*_size = size;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// CreateChild
|
||||
status_t
|
||||
PartitionMapHandle::CreateChild(off_t offset, off_t size,
|
||||
const char* typeString, const char* name, const char* parameters,
|
||||
BMutablePartition** _child)
|
||||
{
|
||||
// check type
|
||||
PartitionType type;
|
||||
if (!type.SetType(typeString) || type.IsEmpty())
|
||||
return B_BAD_VALUE;
|
||||
if (type.IsExtended() && fPartitionMap.ExtendedPartitionIndex() >= 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check name
|
||||
if (name && strlen(name) > 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check parameters
|
||||
// TODO:...
|
||||
|
||||
// get a spare primary partition
|
||||
PrimaryPartition* primary = NULL;
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
if (fPartitionMap.PrimaryPartitionAt(i)->IsEmpty()) {
|
||||
primary = fPartitionMap.PrimaryPartitionAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!primary)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// offset properly aligned?
|
||||
if (offset != sector_align(offset) || size != sector_align(size))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// check the free space situation
|
||||
BPartitioningInfo info;
|
||||
status_t error = GetPartitioningInfo(&info);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
bool foundSpace = false;
|
||||
off_t end = offset + size;
|
||||
int32 spacesCount = info.CountPartitionableSpaces();
|
||||
for (int32 i = 0; i < spacesCount; i++) {
|
||||
off_t spaceOffset, spaceSize;
|
||||
info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
||||
off_t spaceEnd = spaceOffset + spaceSize;
|
||||
|
||||
if (offset >= spaceOffset && end <= spaceEnd) {
|
||||
foundSpace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundSpace)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// everything looks good, do it
|
||||
|
||||
// create the child
|
||||
// (Note: the primary partition index is indeed the child index, since
|
||||
// we picked the first empty primary partition.)
|
||||
BMutablePartition* partition = Partition();
|
||||
BMutablePartition* child;
|
||||
error = partition->CreateChild(primary->Index(), typeString, NULL,
|
||||
parameters, &child);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// init the child
|
||||
child->SetOffset(offset);
|
||||
child->SetSize(size);
|
||||
child->SetBlockSize(SECTOR_SIZE);
|
||||
//child->SetFlags(0);
|
||||
child->SetChildCookie(primary);
|
||||
|
||||
// init the primary partition
|
||||
bool active = false;
|
||||
// TODO: Get from parameters!
|
||||
primary->SetTo(offset, size, type.Type(), active);
|
||||
|
||||
// TODO: If the child is an extended partition, we should trigger its
|
||||
// initialization.
|
||||
|
||||
*_child = child;
|
||||
return B_OK;
|
||||
}
|
||||
|
67
src/add-ons/disk_systems/intel/PartitionMapAddOn.h
Normal file
67
src/add-ons/disk_systems/intel/PartitionMapAddOn.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2007, Ingo Weinhold, bonefish@users.sf.net.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _PARTITION_MAP_ADD_ON_H
|
||||
#define _PARTITION_MAP_ADD_ON_H
|
||||
|
||||
#include <DiskSystemAddOn.h>
|
||||
|
||||
#include "PartitionMap.h"
|
||||
|
||||
|
||||
class PartitionMapAddOn : public BDiskSystemAddOn {
|
||||
public:
|
||||
PartitionMapAddOn();
|
||||
virtual ~PartitionMapAddOn();
|
||||
|
||||
virtual status_t CreatePartitionHandle(
|
||||
BMutablePartition* partition,
|
||||
BPartitionHandle** handle);
|
||||
|
||||
virtual bool CanInitialize(
|
||||
const BMutablePartition* partition);
|
||||
virtual status_t GetInitializationParameterEditor(
|
||||
const BMutablePartition* partition,
|
||||
BDiskDeviceParameterEditor** editor);
|
||||
virtual status_t ValidateInitialize(
|
||||
const BMutablePartition* partition,
|
||||
BString* name, const char* parameters);
|
||||
virtual status_t Initialize(BMutablePartition* partition,
|
||||
const char* name, const char* parameters,
|
||||
BPartitionHandle** handle);
|
||||
};
|
||||
|
||||
|
||||
class PartitionMapHandle : public BPartitionHandle {
|
||||
public:
|
||||
PartitionMapHandle(
|
||||
BMutablePartition* partition);
|
||||
virtual ~PartitionMapHandle();
|
||||
|
||||
status_t Init();
|
||||
|
||||
virtual uint32 SupportedOperations(uint32 mask);
|
||||
virtual uint32 SupportedChildOperations(
|
||||
const BMutablePartition* child,
|
||||
uint32 mask);
|
||||
|
||||
virtual status_t GetPartitioningInfo(BPartitioningInfo* info);
|
||||
|
||||
virtual status_t GetChildCreationParameterEditor(
|
||||
const char* type,
|
||||
BDiskDeviceParameterEditor** editor);
|
||||
virtual status_t ValidateCreateChild(off_t* offset,
|
||||
off_t* size, const char* type,
|
||||
BString* name, const char* parameters);
|
||||
virtual status_t CreateChild(off_t offset, off_t size,
|
||||
const char* type, const char* name,
|
||||
const char* parameters,
|
||||
BMutablePartition** child);
|
||||
|
||||
private:
|
||||
PartitionMap fPartitionMap;
|
||||
};
|
||||
|
||||
|
||||
#endif // _PARTITION_MAP_ADD_ON_H
|
Loading…
Reference in New Issue
Block a user