* Added open_partition to disk_device_manager
* Rewrote PartitionMapWriter * Updated style to match current style guide for the intel partitioning system. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32235 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -101,6 +101,8 @@ partition_data *get_partition(partition_id partitionID);
|
|||||||
partition_data *get_parent_partition(partition_id partitionID);
|
partition_data *get_parent_partition(partition_id partitionID);
|
||||||
partition_data *get_child_partition(partition_id partitionID, int32 index);
|
partition_data *get_child_partition(partition_id partitionID, int32 index);
|
||||||
|
|
||||||
|
int open_partition(partition_id partitionID, int openMode);
|
||||||
|
|
||||||
// partition write access
|
// partition write access
|
||||||
// (write lock required)
|
// (write lock required)
|
||||||
partition_data *create_child_partition(partition_id partitionID, int32 index,
|
partition_data *create_child_partition(partition_id partitionID, int32 index,
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static const uint32 kDiskSystemFlags =
|
|||||||
// | B_DISK_SYSTEM_SUPPORTS_MOVING
|
// | B_DISK_SYSTEM_SUPPORTS_MOVING
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME
|
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_NAME
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
|
// | B_DISK_SYSTEM_SUPPORTS_SETTING_CONTENT_PARAMETERS
|
||||||
| B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
// | B_DISK_SYSTEM_SUPPORTS_INITIALIZING
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
// | B_DISK_SYSTEM_SUPPORTS_CONTENT_NAME
|
||||||
|
|
||||||
// | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
// | B_DISK_SYSTEM_SUPPORTS_RESIZING_CHILD
|
||||||
@@ -92,7 +92,7 @@ bool
|
|||||||
ExtendedPartitionAddOn::CanInitialize(const BMutablePartition* partition)
|
ExtendedPartitionAddOn::CanInitialize(const BMutablePartition* partition)
|
||||||
{
|
{
|
||||||
// If it's big enough, we can initialize it.
|
// If it's big enough, we can initialize it.
|
||||||
return partition->Size() >= 2 * partition->BlockSize();
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ ExtendedPartitionHandle::Init()
|
|||||||
uint32
|
uint32
|
||||||
ExtendedPartitionHandle::SupportedOperations(uint32 mask)
|
ExtendedPartitionHandle::SupportedOperations(uint32 mask)
|
||||||
{
|
{
|
||||||
uint32 flags = B_DISK_SYSTEM_SUPPORTS_INITIALIZING;
|
uint32 flags = 0;//B_DISK_SYSTEM_SUPPORTS_INITIALIZING;
|
||||||
|
|
||||||
// creating child
|
// creating child
|
||||||
if (mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) {
|
if (mask & B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD) {
|
||||||
@@ -254,10 +254,25 @@ ExtendedPartitionHandle::GetNextSupportedType(const BMutablePartition* child,
|
|||||||
TRACE("%p->ExtendedPartitionHandle::GetNextSupportedType(child: %p, "
|
TRACE("%p->ExtendedPartitionHandle::GetNextSupportedType(child: %p, "
|
||||||
"cookie: %ld)\n", this, child, *cookie);
|
"cookie: %ld)\n", this, child, *cookie);
|
||||||
|
|
||||||
if (*cookie != 0)
|
int32 index = *cookie;
|
||||||
|
const partition_type* nextType;
|
||||||
|
PartitionMap partitionMap;
|
||||||
|
while (true) {
|
||||||
|
nextType = partitionMap.GetNextSupportedPartitionType(index);
|
||||||
|
if (nextType == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
*cookie = *cookie + 1;
|
index++;
|
||||||
*type = kPartitionTypeIntelLogical;
|
if (nextType->used
|
||||||
|
&& strcmp(nextType->name, kPartitionTypeIntelExtended) != 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nextType)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
type->SetTo(nextType->name);
|
||||||
|
*cookie = index;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,39 +281,22 @@ ExtendedPartitionHandle::GetNextSupportedType(const BMutablePartition* child,
|
|||||||
status_t
|
status_t
|
||||||
ExtendedPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
|
ExtendedPartitionHandle::GetPartitioningInfo(BPartitioningInfo* info)
|
||||||
{
|
{
|
||||||
// NOTE stippi: At first I tried to use the fPrimaryPartition
|
|
||||||
// here but it does not return any LogicalPartitions. What
|
|
||||||
// happens now is probably what used to happen before, though
|
|
||||||
// I don't understand *where*, since this handle type never
|
|
||||||
// implemented this virtual function.
|
|
||||||
|
|
||||||
// init to the full size (minus the first sector)
|
// init to the full size (minus the first sector)
|
||||||
BMutablePartition* partition = Partition();
|
BMutablePartition* partition = Partition();
|
||||||
off_t offset = partition->Offset();// + SECTOR_SIZE;
|
off_t offset = partition->Offset();
|
||||||
off_t size = partition->Size();//- SECTOR_SIZE;
|
off_t size = partition->Size();
|
||||||
status_t error = info->SetTo(offset, size);
|
status_t error = info->SetTo(offset, size);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
// exclude the space of the existing logical partitions
|
// exclude the space of the existing logical partitions
|
||||||
int32 count = partition->CountChildren();
|
int32 count = partition->CountChildren();
|
||||||
printf("%ld logical partitions\n", count);
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
BMutablePartition* child = partition->ChildAt(i);
|
BMutablePartition* child = partition->ChildAt(i);
|
||||||
// TODO: Does this correctly account for the partition table
|
|
||||||
// sectors? Preceeding each logical partition should be a
|
|
||||||
// sector for the partition table entry. Those entries form
|
|
||||||
// the linked list of "inner extended partition" + "real partition"
|
|
||||||
// Following the logic above (copied from PartitionMapAddOn),
|
|
||||||
// the outer size includes the first sector and is therefor
|
|
||||||
// what we need here.
|
|
||||||
error = info->ExcludeOccupiedSpace(child->Offset(), child->Size());
|
error = info->ExcludeOccupiedSpace(child->Offset(), child->Size());
|
||||||
printf(" %ld: offset = %lld (relative: %lld), size = %lld\n", i,
|
|
||||||
child->Offset(), child->Offset() - offset, child->Size());
|
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
info->PrintToStream();
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -309,7 +307,6 @@ status_t
|
|||||||
ExtendedPartitionHandle::GetChildCreationParameterEditor(const char* type,
|
ExtendedPartitionHandle::GetChildCreationParameterEditor(const char* type,
|
||||||
BPartitionParameterEditor** editor)
|
BPartitionParameterEditor** editor)
|
||||||
{
|
{
|
||||||
// TODO: We actually need an editor here.
|
|
||||||
*editor = NULL;
|
*editor = NULL;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -321,102 +318,98 @@ ExtendedPartitionHandle::ValidateCreateChild(off_t* _offset, off_t* _size,
|
|||||||
const char* typeString, BString* name, const char* parameters)
|
const char* typeString, BString* name, const char* parameters)
|
||||||
{
|
{
|
||||||
// check type
|
// check type
|
||||||
if (!typeString || strcmp(typeString, kPartitionTypeIntelLogical) != 0)
|
if (!typeString)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// check name
|
// check name
|
||||||
if (name)
|
if (name)
|
||||||
name->Truncate(0);
|
name->Truncate(0);
|
||||||
|
|
||||||
// check parameters
|
// check the free space situation
|
||||||
// TODO:...
|
BPartitioningInfo info;
|
||||||
|
status_t error = GetPartitioningInfo(&info);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
return B_NOT_SUPPORTED;
|
// any space in the partition at all?
|
||||||
// // check the free space situation
|
int32 spacesCount = info.CountPartitionableSpaces();
|
||||||
// BPartitioningInfo info;
|
if (spacesCount == 0)
|
||||||
// status_t error = GetPartitioningInfo(&info);
|
return B_BAD_VALUE;
|
||||||
// if (error != B_OK)
|
|
||||||
// return error;
|
// check offset and size
|
||||||
//
|
off_t offset = sector_align(*_offset, Partition()->BlockSize());
|
||||||
// // any space in the partition at all?
|
off_t size = sector_align(*_size, Partition()->BlockSize());
|
||||||
// int32 spacesCount = info.CountPartitionableSpaces();
|
// TODO: Rather round size up?
|
||||||
// if (spacesCount == 0)
|
off_t end = offset + size;
|
||||||
// return B_BAD_VALUE;
|
|
||||||
//
|
// get the first partitionable space the requested interval intersects with
|
||||||
// // check offset and size
|
int32 spaceIndex = -1;
|
||||||
// off_t offset = sector_align(*_offset);
|
int32 closestSpaceIndex = -1;
|
||||||
// off_t size = sector_align(*_size);
|
off_t closestSpaceDistance = 0;
|
||||||
// // TODO: Rather round size up?
|
for (int32 i = 0; i < spacesCount; i++) {
|
||||||
// off_t end = offset + size;
|
off_t spaceOffset, spaceSize;
|
||||||
//
|
info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
||||||
// // get the first partitionable space the requested interval intersects with
|
off_t spaceEnd = spaceOffset + spaceSize;
|
||||||
// int32 spaceIndex = -1;
|
|
||||||
// int32 closestSpaceIndex = -1;
|
if (spaceOffset >= offset && spaceOffset < end
|
||||||
// off_t closestSpaceDistance = 0;
|
|| offset >= spaceOffset && offset < spaceEnd) {
|
||||||
// for (int32 i = 0; i < spacesCount; i++) {
|
spaceIndex = i;
|
||||||
// off_t spaceOffset, spaceSize;
|
break;
|
||||||
// info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
}
|
||||||
// off_t spaceEnd = spaceOffset + spaceSize;
|
|
||||||
//
|
off_t distance;
|
||||||
// if (spaceOffset >= offset && spaceOffset < end
|
if (offset < spaceOffset)
|
||||||
// || offset >= spaceOffset && offset < spaceEnd) {
|
distance = spaceOffset - end;
|
||||||
// spaceIndex = i;
|
else
|
||||||
// break;
|
distance = spaceEnd - offset;
|
||||||
// }
|
|
||||||
//
|
if (closestSpaceIndex == -1 || distance < closestSpaceDistance) {
|
||||||
// off_t distance;
|
closestSpaceIndex = i;
|
||||||
// if (offset < spaceOffset)
|
closestSpaceDistance = distance;
|
||||||
// distance = spaceOffset - end;
|
}
|
||||||
// else
|
}
|
||||||
// distance = spaceEnd - offset;
|
|
||||||
//
|
// get the space we found
|
||||||
// if (closestSpaceIndex == -1 || distance < closestSpaceDistance) {
|
off_t spaceOffset, spaceSize;
|
||||||
// closestSpaceIndex = i;
|
info.GetPartitionableSpaceAt(
|
||||||
// closestSpaceDistance = distance;
|
spaceIndex >= 0 ? spaceIndex : closestSpaceIndex, &spaceOffset,
|
||||||
// }
|
&spaceSize);
|
||||||
// }
|
off_t spaceEnd = spaceOffset + spaceSize;
|
||||||
//
|
|
||||||
// // get the space we found
|
// If the requested intervald doesn't intersect with any space yet, move
|
||||||
// off_t spaceOffset, spaceSize;
|
// it, so that it does.
|
||||||
// info.GetPartitionableSpaceAt(
|
if (spaceIndex < 0) {
|
||||||
// spaceIndex >= 0 ? spaceIndex : closestSpaceIndex, &spaceOffset,
|
spaceIndex = closestSpaceIndex;
|
||||||
// &spaceSize);
|
if (offset < spaceOffset) {
|
||||||
// off_t spaceEnd = spaceOffset + spaceSize;
|
offset = spaceOffset;
|
||||||
//
|
end = offset + size;
|
||||||
// // If the requested intervald doesn't intersect with any space yet, move
|
} else {
|
||||||
// // it, so that it does.
|
end = spaceEnd;
|
||||||
// if (spaceIndex < 0) {
|
offset = end - size;
|
||||||
// spaceIndex = closestSpaceIndex;
|
}
|
||||||
// if (offset < spaceOffset) {
|
}
|
||||||
// offset = spaceOffset;
|
|
||||||
// end = offset + size;
|
// move/shrink the interval, so that it fully lies within the space
|
||||||
// } else {
|
if (offset < spaceOffset) {
|
||||||
// end = spaceEnd;
|
offset = spaceOffset;
|
||||||
// offset = end - size;
|
end = offset + size;
|
||||||
// }
|
if (end > spaceEnd) {
|
||||||
// }
|
end = spaceEnd;
|
||||||
//
|
size = end - offset;
|
||||||
// // move/shrink the interval, so that it fully lies within the space
|
}
|
||||||
// if (offset < spaceOffset) {
|
} else if (end > spaceEnd) {
|
||||||
// offset = spaceOffset;
|
end = spaceEnd;
|
||||||
// end = offset + size;
|
offset = end - size;
|
||||||
// if (end > spaceEnd) {
|
if (offset < spaceOffset) {
|
||||||
// end = spaceEnd;
|
offset = spaceOffset;
|
||||||
// size = end - offset;
|
size = end - offset;
|
||||||
// }
|
}
|
||||||
// } else if (end > spaceEnd) {
|
}
|
||||||
// end = spaceEnd;
|
|
||||||
// offset = end - size;
|
*_offset = offset;
|
||||||
// if (offset < spaceOffset) {
|
*_size = size;
|
||||||
// offset = spaceOffset;
|
|
||||||
// size = end - offset;
|
return B_OK;
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// *_offset = offset;
|
|
||||||
// *_size = size;
|
|
||||||
//
|
|
||||||
// return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -427,73 +420,69 @@ ExtendedPartitionHandle::CreateChild(off_t offset, off_t size,
|
|||||||
BMutablePartition** _child)
|
BMutablePartition** _child)
|
||||||
{
|
{
|
||||||
// check type
|
// check type
|
||||||
if (!typeString || strcmp(typeString, kPartitionTypeIntelLogical) != 0)
|
PartitionType type;
|
||||||
|
if (!type.SetType(typeString) || type.IsEmpty())
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// check name
|
// check name
|
||||||
if (name && strlen(name) > 0)
|
if (name && strlen(name) > 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// check parameters
|
// offset properly aligned?
|
||||||
// TODO:...
|
if (offset != sector_align(offset, Partition()->BlockSize())
|
||||||
|
|| size != sector_align(size, Partition()->BlockSize()))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return B_NOT_SUPPORTED;
|
// check the free space situation
|
||||||
// // offset properly aligned?
|
BPartitioningInfo info;
|
||||||
// if (offset != sector_align(offset) || size != sector_align(size))
|
status_t error = GetPartitioningInfo(&info);
|
||||||
// return B_BAD_VALUE;
|
if (error != B_OK)
|
||||||
//
|
return error;
|
||||||
// // check the free space situation
|
|
||||||
// BPartitioningInfo info;
|
bool foundSpace = false;
|
||||||
// status_t error = GetPartitioningInfo(&info);
|
off_t end = offset + size;
|
||||||
// if (error != B_OK)
|
int32 spacesCount = info.CountPartitionableSpaces();
|
||||||
// return error;
|
for (int32 i = 0; i < spacesCount; i++) {
|
||||||
//
|
off_t spaceOffset, spaceSize;
|
||||||
// bool foundSpace = false;
|
info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
||||||
// off_t end = offset + size;
|
off_t spaceEnd = spaceOffset + spaceSize;
|
||||||
// int32 spacesCount = info.CountPartitionableSpaces();
|
|
||||||
// for (int32 i = 0; i < spacesCount; i++) {
|
if (offset >= spaceOffset && end <= spaceEnd) {
|
||||||
// off_t spaceOffset, spaceSize;
|
foundSpace = true;
|
||||||
// info.GetPartitionableSpaceAt(i, &spaceOffset, &spaceSize);
|
break;
|
||||||
// off_t spaceEnd = spaceOffset + spaceSize;
|
}
|
||||||
//
|
}
|
||||||
// if (offset >= spaceOffset && end <= spaceEnd) {
|
|
||||||
// foundSpace = true;
|
if (!foundSpace)
|
||||||
// break;
|
return B_BAD_VALUE;
|
||||||
// }
|
|
||||||
// }
|
// everything looks good, do it
|
||||||
//
|
// create the child
|
||||||
// if (!foundSpace)
|
BMutablePartition* child;
|
||||||
// return B_BAD_VALUE;
|
error = Partition()->CreateChild(-1, typeString,
|
||||||
//
|
NULL, parameters, &child);
|
||||||
// // everything looks good, do it
|
if (error != B_OK)
|
||||||
//
|
return error;
|
||||||
// // create the child
|
|
||||||
// // (Note: the primary partition index is indeed the child index, since
|
// init the child
|
||||||
// // we picked the first empty primary partition.)
|
child->SetOffset(offset);
|
||||||
// BMutablePartition* partition = Partition();
|
child->SetSize(size);
|
||||||
// BMutablePartition* child;
|
child->SetBlockSize(Partition()->BlockSize());
|
||||||
// error = partition->CreateChild(primary->Index(), typeString, NULL,
|
//child->SetFlags(0);
|
||||||
// parameters, &child);
|
child->SetChildCookie(Partition());
|
||||||
// if (error != B_OK)
|
|
||||||
// return error;
|
*_child = child;
|
||||||
//
|
return B_OK;
|
||||||
// // 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// DeleteChild
|
||||||
|
status_t
|
||||||
|
ExtendedPartitionHandle::DeleteChild(BMutablePartition* child)
|
||||||
|
{
|
||||||
|
BMutablePartition* parent = child->Parent();
|
||||||
|
status_t error = parent->DeleteChild(child);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ public:
|
|||||||
const char* type, const char* name,
|
const char* type, const char* name,
|
||||||
const char* parameters,
|
const char* parameters,
|
||||||
BMutablePartition** child);
|
BMutablePartition** child);
|
||||||
|
virtual status_t DeleteChild(BMutablePartition* child);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PrimaryPartition* fPrimaryPartition;
|
PrimaryPartition* fPrimaryPartition;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -356,19 +356,6 @@ Partition::Unset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Partition::GetPartitionDescriptor(partition_descriptor *descriptor,
|
|
||||||
off_t baseOffset) const
|
|
||||||
{
|
|
||||||
descriptor->start = (fOffset - baseOffset) / fBlockSize;
|
|
||||||
descriptor->size = fSize / fBlockSize;
|
|
||||||
descriptor->type = fType;
|
|
||||||
descriptor->active = fActive ? 0x80 : 0x00;
|
|
||||||
descriptor->begin.Unset();
|
|
||||||
descriptor->end.Unset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
void
|
void
|
||||||
Partition::AdjustSize(off_t sessionSize)
|
Partition::AdjustSize(off_t sessionSize)
|
||||||
@@ -389,7 +376,8 @@ Partition::CheckLocation(off_t sessionSize) const
|
|||||||
// lie within the session
|
// lie within the session
|
||||||
if (fPartitionTableOffset % fBlockSize != 0) {
|
if (fPartitionTableOffset % fBlockSize != 0) {
|
||||||
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
|
TRACE(("Partition::CheckLocation() - bad partition table offset: %lld "
|
||||||
"(session: %lld)\n", fPartitionTableOffset, sessionSize));
|
"(session: %lld), (fBlockSize: %ld)\n", fPartitionTableOffset,
|
||||||
|
sessionSize, fBlockSize));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (fOffset % fBlockSize != 0) {
|
if (fOffset % fBlockSize != 0) {
|
||||||
@@ -426,7 +414,8 @@ Partition::CheckLocation(off_t sessionSize) const
|
|||||||
|
|
||||||
|
|
||||||
PrimaryPartition::PrimaryPartition()
|
PrimaryPartition::PrimaryPartition()
|
||||||
: Partition(),
|
:
|
||||||
|
Partition(),
|
||||||
fHead(NULL),
|
fHead(NULL),
|
||||||
fTail(NULL),
|
fTail(NULL),
|
||||||
fLogicalPartitionCount(0)
|
fLogicalPartitionCount(0)
|
||||||
@@ -470,13 +459,13 @@ status_t
|
|||||||
PrimaryPartition::Assign(const PrimaryPartition& other)
|
PrimaryPartition::Assign(const PrimaryPartition& other)
|
||||||
{
|
{
|
||||||
partition_descriptor descriptor;
|
partition_descriptor descriptor;
|
||||||
other.GetPartitionDescriptor(&descriptor, 0);
|
other.GetPartitionDescriptor(&descriptor);
|
||||||
SetTo(&descriptor, 0, other.BlockSize());
|
SetTo(&descriptor, 0, other.BlockSize());
|
||||||
|
|
||||||
const LogicalPartition* otherLogical = other.fHead;
|
const LogicalPartition* otherLogical = other.fHead;
|
||||||
while (otherLogical) {
|
while (otherLogical) {
|
||||||
off_t tableOffset = otherLogical->PartitionTableOffset();
|
off_t tableOffset = otherLogical->PartitionTableOffset();
|
||||||
otherLogical->GetPartitionDescriptor(&descriptor, tableOffset);
|
otherLogical->GetPartitionDescriptor(&descriptor);
|
||||||
|
|
||||||
LogicalPartition* logical = new(nothrow) LogicalPartition(
|
LogicalPartition* logical = new(nothrow) LogicalPartition(
|
||||||
&descriptor, tableOffset, this);
|
&descriptor, tableOffset, this);
|
||||||
@@ -492,6 +481,22 @@ PrimaryPartition::Assign(const PrimaryPartition& other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PrimaryPartition::GetPartitionDescriptor(partition_descriptor* descriptor) const
|
||||||
|
{
|
||||||
|
if (IsEmpty()) {
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
} else {
|
||||||
|
descriptor->start = Offset() / BlockSize();
|
||||||
|
descriptor->size = Size() / BlockSize();
|
||||||
|
descriptor->type = Type();
|
||||||
|
descriptor->active = Active() ? 0x80 : 0x00;
|
||||||
|
descriptor->begin.Unset();
|
||||||
|
descriptor->end.Unset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LogicalPartition*
|
LogicalPartition*
|
||||||
PrimaryPartition::LogicalPartitionAt(int32 index) const
|
PrimaryPartition::LogicalPartitionAt(int32 index) const
|
||||||
{
|
{
|
||||||
@@ -554,7 +559,8 @@ PrimaryPartition::RemoveLogicalPartition(LogicalPartition* partition)
|
|||||||
|
|
||||||
|
|
||||||
LogicalPartition::LogicalPartition()
|
LogicalPartition::LogicalPartition()
|
||||||
: Partition(),
|
:
|
||||||
|
Partition(),
|
||||||
fPrimary(NULL),
|
fPrimary(NULL),
|
||||||
fNext(NULL),
|
fNext(NULL),
|
||||||
fPrevious(NULL)
|
fPrevious(NULL)
|
||||||
@@ -564,7 +570,8 @@ LogicalPartition::LogicalPartition()
|
|||||||
|
|
||||||
LogicalPartition::LogicalPartition(const partition_descriptor* descriptor,
|
LogicalPartition::LogicalPartition(const partition_descriptor* descriptor,
|
||||||
off_t tableOffset, PrimaryPartition* primary)
|
off_t tableOffset, PrimaryPartition* primary)
|
||||||
: Partition(),
|
:
|
||||||
|
Partition(),
|
||||||
fPrimary(NULL),
|
fPrimary(NULL),
|
||||||
fNext(NULL),
|
fNext(NULL),
|
||||||
fPrevious(NULL)
|
fPrevious(NULL)
|
||||||
@@ -622,6 +629,27 @@ LogicalPartition::Unset()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LogicalPartition::GetPartitionDescriptor(partition_descriptor* descriptor,
|
||||||
|
bool inner) const
|
||||||
|
{
|
||||||
|
PrimaryPartition* primary = GetPrimaryPartition();
|
||||||
|
if (inner) {
|
||||||
|
descriptor->start = (PartitionTableOffset() - primary->Offset())
|
||||||
|
/ BlockSize();
|
||||||
|
descriptor->type = primary->Type();
|
||||||
|
} else {
|
||||||
|
descriptor->start = (Offset() - PartitionTableOffset()) / BlockSize();
|
||||||
|
descriptor->type = Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
descriptor->size = Size() / BlockSize();
|
||||||
|
descriptor->active = 0x00;
|
||||||
|
descriptor->begin.Unset();
|
||||||
|
descriptor->end.Unset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - PartitionMap
|
// #pragma mark - PartitionMap
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -169,9 +169,6 @@ public:
|
|||||||
uint32 BlockSize() const { return fBlockSize; }
|
uint32 BlockSize() const { return fBlockSize; }
|
||||||
void GetTypeString(char* buffer) const
|
void GetTypeString(char* buffer) const
|
||||||
{ get_partition_type_string(fType, buffer); }
|
{ get_partition_type_string(fType, buffer); }
|
||||||
void GetPartitionDescriptor(
|
|
||||||
partition_descriptor* descriptor,
|
|
||||||
off_t baseOffset) const;
|
|
||||||
|
|
||||||
void SetPartitionTableOffset(off_t offset)
|
void SetPartitionTableOffset(off_t offset)
|
||||||
{ fPartitionTableOffset = offset; }
|
{ fPartitionTableOffset = offset; }
|
||||||
@@ -183,6 +180,8 @@ public:
|
|||||||
{ fType = type; }
|
{ fType = type; }
|
||||||
void SetActive(bool active)
|
void SetActive(bool active)
|
||||||
{ fActive = active; }
|
{ fActive = active; }
|
||||||
|
void SetBlockSize(uint32 blockSize)
|
||||||
|
{ fBlockSize = blockSize; }
|
||||||
|
|
||||||
bool CheckLocation(off_t sessionSize) const;
|
bool CheckLocation(off_t sessionSize) const;
|
||||||
#ifdef _BOOT_MODE
|
#ifdef _BOOT_MODE
|
||||||
@@ -215,6 +214,9 @@ public:
|
|||||||
|
|
||||||
int32 Index() const { return fIndex; }
|
int32 Index() const { return fIndex; }
|
||||||
void SetIndex(int32 index) { fIndex = index; }
|
void SetIndex(int32 index) { fIndex = index; }
|
||||||
|
void GetPartitionDescriptor(
|
||||||
|
partition_descriptor* descriptor) const;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
|
|
||||||
// only if extended
|
// only if extended
|
||||||
@@ -249,6 +251,10 @@ public:
|
|||||||
bool active, off_t tableOffset,
|
bool active, off_t tableOffset,
|
||||||
PrimaryPartition* primary);
|
PrimaryPartition* primary);
|
||||||
void Unset();
|
void Unset();
|
||||||
|
void GetPartitionDescriptor(
|
||||||
|
partition_descriptor* descriptor,
|
||||||
|
bool inner = false) const;
|
||||||
|
|
||||||
|
|
||||||
void SetPrimaryPartition(PrimaryPartition* primary)
|
void SetPrimaryPartition(PrimaryPartition* primary)
|
||||||
{ fPrimary = primary; }
|
{ fPrimary = primary; }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Tomas Kucera, kucerat@centrum.cz
|
* Bryce Groff, brycegroff@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "PartitionMapWriter.h"
|
#include "PartitionMapWriter.h"
|
||||||
@@ -34,293 +34,225 @@ using std::nothrow;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// TODO: get rid of this - there is no such thing as a fixed sector size!
|
bool
|
||||||
static const uint32 SECTOR_SIZE = 512;
|
check_logical_location(const LogicalPartition* child,
|
||||||
|
const PrimaryPartition* parent)
|
||||||
|
{
|
||||||
|
if (child->PartitionTableOffset() % child->BlockSize() != 0) {
|
||||||
|
TRACE(("check_logical_location() - PartitionTableOffset: %lld not a "
|
||||||
|
"multiple of media's block size: %ld\n",
|
||||||
|
child->PartitionTableOffset(), child->BlockSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->Offset() % child->BlockSize() != 0) {
|
||||||
|
TRACE(("check_logical_location() - Parition offset: %lld "
|
||||||
|
"is not a multiple of block size: %ld\n", child->Offset(),
|
||||||
|
child->BlockSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->Size() % child->BlockSize() != 0) {
|
||||||
|
TRACE(("check_logical_location() - Size: (%lld) is not a multiple of"
|
||||||
|
" block size: (%ld)\n", child->Size(), child->BlockSize()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->PartitionTableOffset() < parent->Offset()
|
||||||
|
|| child->PartitionTableOffset() >= parent->Offset()
|
||||||
|
+ parent->Size()) {
|
||||||
|
TRACE(("check_logical_location() - Partition table: (%lld) not within "
|
||||||
|
"extended partition (start: %lld), (end: %lld)\n",
|
||||||
|
child->PartitionTableOffset(), parent->Offset(), parent->Offset()
|
||||||
|
+ parent->Size()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (child->Offset() + child->Size() > parent->Offset() + parent->Size()) {
|
||||||
|
TRACE(("check_logical_location() - logical paritition does not lie "
|
||||||
|
"within extended partition\n"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
PartitionMapWriter::PartitionMapWriter(int deviceFD, uint32 blockSize)
|
||||||
/*! \brief Creates the writer.
|
|
||||||
|
|
||||||
\param deviceFD File descriptor.
|
|
||||||
\param sessionOffset Disk offset of the partition with partitioning system.
|
|
||||||
\param sessionSize Size of the partition with partitioning system.
|
|
||||||
*/
|
|
||||||
PartitionMapWriter::PartitionMapWriter(int deviceFD, off_t sessionOffset,
|
|
||||||
off_t sessionSize)
|
|
||||||
:
|
:
|
||||||
fDeviceFD(deviceFD),
|
fDeviceFD(deviceFD),
|
||||||
fSessionOffset(sessionOffset),
|
fBlockSize(blockSize)
|
||||||
fSessionSize(sessionSize),
|
|
||||||
fMap(NULL)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
|
||||||
PartitionMapWriter::~PartitionMapWriter()
|
PartitionMapWriter::~PartitionMapWriter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// WriteMBR
|
|
||||||
/*! \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.
|
|
||||||
\param map Pointer to the PartitionMap structure describing disk partitions.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::WriteMBR(const PartitionMap *map, bool clearSectors)
|
PartitionMapWriter::WriteMBR(const PartitionMap* map, bool clearCode)
|
||||||
{
|
{
|
||||||
if (!map)
|
if (map == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
fMap = map;
|
partition_table partitionTable;
|
||||||
|
if (clearCode) {
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
} else {
|
||||||
|
status_t error = _ReadBlock(0, partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 sector[SECTOR_SIZE];
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
partition_table* pts = (partition_table*)sector;
|
|
||||||
|
|
||||||
// If we shall not clear the first two sectors, we need to read the first
|
for (int i = 0; i < 4; i++) {
|
||||||
// sector in, first.
|
partition_descriptor* descriptor = &partitionTable.table[i];
|
||||||
status_t error = B_OK;
|
const PrimaryPartition* partition = map->PrimaryPartitionAt(i);
|
||||||
if (clearSectors)
|
|
||||||
memset(sector, 0, SECTOR_SIZE);
|
partition->GetPartitionDescriptor(descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t error = _WriteBlock(0, partitionTable);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PartitionMapWriter::WriteLogical(const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary, bool clearCode)
|
||||||
|
{
|
||||||
|
if (logical == NULL || primary == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (!check_logical_location(logical, primary))
|
||||||
|
return B_BAD_DATA;
|
||||||
|
|
||||||
|
partition_table partitionTable;
|
||||||
|
if (clearCode) {
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
} else {
|
||||||
|
status_t error = _ReadBlock(logical->PartitionTableOffset(),
|
||||||
|
partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
|
|
||||||
|
partition_descriptor* descriptor = &partitionTable.table[0];
|
||||||
|
logical->GetPartitionDescriptor(descriptor);
|
||||||
|
|
||||||
|
descriptor = &partitionTable.table[1];
|
||||||
|
if (logical->Next() != NULL)
|
||||||
|
logical->Next()->GetPartitionDescriptor(descriptor, true);
|
||||||
else
|
else
|
||||||
error = _ReadSector(0, pts);
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
|
||||||
if (error == B_OK) {
|
// last two descriptors are empty
|
||||||
error = _WritePrimary(pts);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = _WriteSector(0, pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear the second sector, if desired. We do that to make the partition
|
|
||||||
// unrecognizable by BFS.
|
|
||||||
if (error == B_OK && clearSectors) {
|
|
||||||
memset(sector, 0, SECTOR_SIZE);
|
|
||||||
error = _WriteSector(SECTOR_SIZE, pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
fMap = NULL;
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// WriteLogical
|
|
||||||
/*! \brief Writes Partition Table Sector of the logical \a partition to the
|
|
||||||
disk.
|
|
||||||
|
|
||||||
This function ensures that the connection of the following linked list
|
|
||||||
of logical partitions will be correct. It does nothing with the connection
|
|
||||||
of previous logical partitions (call this function on previous logical
|
|
||||||
partition to ensure it).
|
|
||||||
|
|
||||||
\param pts Pointer to \c partition_table.
|
|
||||||
\param partition Pointer to the logical partition.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::WriteLogical(partition_table* pts,
|
|
||||||
const LogicalPartition* partition)
|
|
||||||
{
|
|
||||||
if (partition == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
partition_table _pts;
|
|
||||||
if (pts == NULL) {
|
|
||||||
// no partition table given, use stack based partition table and read
|
|
||||||
// from disk first
|
|
||||||
pts = &_pts;
|
|
||||||
status_t error = _ReadSector(partition->PartitionTableOffset(), pts);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t error = _WriteExtended(pts, partition, partition->Next());
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return _WriteSector(partition->PartitionTableOffset(), pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// WriteExtendedHead
|
|
||||||
/*! \brief Writes Extended Boot Record to the first sector of Extended
|
|
||||||
Partition.
|
|
||||||
|
|
||||||
Writes the head of linked list describing logical partitions.
|
|
||||||
|
|
||||||
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.
|
|
||||||
\param firstPartition Pointer to the first logical partition.
|
|
||||||
*/
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::WriteExtendedHead(partition_table* pts,
|
|
||||||
const LogicalPartition* firstPartition)
|
|
||||||
{
|
|
||||||
LogicalPartition partition;
|
|
||||||
if (firstPartition != NULL)
|
|
||||||
partition.SetPrimaryPartition(firstPartition->GetPrimaryPartition());
|
|
||||||
|
|
||||||
partition_table _pts;
|
|
||||||
if (pts == NULL) {
|
|
||||||
// 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)
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t error = _WriteExtended(pts, &partition, firstPartition);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
return _WriteSector(0, pts);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - fill a partition table in memory
|
|
||||||
|
|
||||||
|
|
||||||
// _WritePrimary
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::_WritePrimary(partition_table* pts)
|
|
||||||
{
|
|
||||||
if (pts == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// write the signature
|
|
||||||
pts->signature = kPartitionTableSectorSignature;
|
|
||||||
|
|
||||||
// write the table
|
|
||||||
for (int32 i = 0; i < 4; i++) {
|
|
||||||
partition_descriptor *descriptor = &pts->table[i];
|
|
||||||
const PrimaryPartition *partition = fMap->PrimaryPartitionAt(i);
|
|
||||||
|
|
||||||
// ignore, if location is bad
|
|
||||||
if (!partition->CheckLocation(fSessionSize)) {
|
|
||||||
TRACE(("intel: _WritePrimary(): partition %ld: bad location, "
|
|
||||||
"ignoring\n", i));
|
|
||||||
return B_BAD_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
partition->GetPartitionDescriptor(descriptor, 0);
|
|
||||||
// TODO: Should this be fSessionOffset?!
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// _WriteExtended
|
|
||||||
status_t
|
|
||||||
PartitionMapWriter::_WriteExtended(partition_table *pts,
|
|
||||||
const LogicalPartition *partition, const LogicalPartition *next)
|
|
||||||
{
|
|
||||||
if (pts == NULL || partition == NULL)
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
// write the signature
|
|
||||||
pts->signature = kPartitionTableSectorSignature;
|
|
||||||
|
|
||||||
// check the partition's location
|
|
||||||
if (!partition->CheckLocation(fSessionSize)) {
|
|
||||||
TRACE(("intel: _WriteExtended(): Invalid partition "
|
|
||||||
"location: pts: %lld, offset: %lld, size: %lld, "
|
|
||||||
"fSessionSize: %lld\n",
|
|
||||||
partition->PartitionTableOffset(), partition->Offset(),
|
|
||||||
partition->Size(), fSessionSize));
|
|
||||||
return B_BAD_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: The OS/2 boot manager needs the first entry to describe the
|
|
||||||
// data partition, while the second entry should describe the "inner
|
|
||||||
// extended" partition.
|
|
||||||
|
|
||||||
// write the table
|
|
||||||
partition_descriptor* descriptor = &(pts->table[0]);
|
|
||||||
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 partition table location (start sector of
|
|
||||||
// the inner extended partition).
|
|
||||||
descriptor = &pts->table[1];
|
|
||||||
LogicalPartition extended;
|
|
||||||
if (next) {
|
|
||||||
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 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->PartitionTableOffset()));
|
|
||||||
|
|
||||||
// Use the same extended partition type as the primary extended
|
|
||||||
// partition.
|
|
||||||
extended.SetType(partition->GetPrimaryPartition()->Type());
|
|
||||||
|
|
||||||
extended.GetPartitionDescriptor(descriptor, 0);
|
|
||||||
|
|
||||||
// Unsetting to get an empty descriptor for the remaining slots.
|
|
||||||
extended.Unset();
|
|
||||||
} else
|
|
||||||
extended.GetPartitionDescriptor(descriptor, 0);
|
|
||||||
|
|
||||||
// last two descriptors are empty ("extended" is unset)
|
|
||||||
for (int32 i = 2; i < 4; i++) {
|
for (int32 i = 2; i < 4; i++) {
|
||||||
descriptor = &(pts->table[i]);
|
descriptor = &partitionTable.table[i];
|
||||||
extended.GetPartitionDescriptor(descriptor, 0);
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t error = _WriteBlock(logical->PartitionTableOffset(),
|
||||||
|
partitionTable);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PartitionMapWriter::WriteExtendedHead(const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary, bool clearCode)
|
||||||
|
{
|
||||||
|
if (primary == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
partition_table partitionTable;
|
||||||
|
if (clearCode) {
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
} else {
|
||||||
|
status_t error = _ReadBlock(primary->Offset(), partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
|
partition_descriptor* descriptor;
|
||||||
|
if (logical == NULL) {
|
||||||
|
for (int32 i = 0; i < 4; i++) {
|
||||||
|
descriptor = &partitionTable.table[i];
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogicalPartition partition;
|
||||||
|
partition.SetPartitionTableOffset(primary->Offset());
|
||||||
|
partition.SetBlockSize(logical->BlockSize());
|
||||||
|
partition.SetOffset(logical->Offset());
|
||||||
|
partition.SetSize(logical->Size());
|
||||||
|
partition.SetType(logical->Type());
|
||||||
|
|
||||||
|
// set the logicals partition table to the correct location
|
||||||
|
descriptor = &partitionTable.table[0];
|
||||||
|
partition.GetPartitionDescriptor(descriptor);
|
||||||
|
|
||||||
|
descriptor = &partitionTable.table[1];
|
||||||
|
LogicalPartition* next = logical->Next();
|
||||||
|
if (next != NULL)
|
||||||
|
next->GetPartitionDescriptor(descriptor, true);
|
||||||
|
else
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
|
||||||
|
// last two descriptors are empty
|
||||||
|
for (int32 i = 2; i < 4; i++) {
|
||||||
|
descriptor = &partitionTable.table[i];
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t error = _WriteBlock(primary->Offset(), partitionTable);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - to/from disk
|
|
||||||
|
|
||||||
|
|
||||||
// _ReadSector
|
|
||||||
/*! \brief Reads the sector from the disk.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::_ReadSector(off_t offset, partition_table* pts)
|
PartitionMapWriter::ClearExtendedHead(const PrimaryPartition* primary)
|
||||||
{
|
{
|
||||||
int32 toRead = sizeof(partition_table);
|
if (primary == NULL)
|
||||||
// same as SECTOR_SIZE actually
|
|
||||||
|
|
||||||
// check the offset
|
|
||||||
if (offset < 0 || offset + toRead > fSessionSize) {
|
|
||||||
TRACE(("intel: _ReadSector(): bad offset: %Ld\n", offset));
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
partition_table partitionTable;
|
||||||
|
partitionTable.clear_code_area();
|
||||||
|
partitionTable.signature = kPartitionTableSectorSignature;
|
||||||
|
|
||||||
|
partition_descriptor* descriptor;
|
||||||
|
for (int32 i = 0; i < 4; i++) {
|
||||||
|
descriptor = &partitionTable.table[i];
|
||||||
|
memset(descriptor, 0, sizeof(partition_descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
// read
|
status_t error = _WriteBlock(primary->Offset(), partitionTable);
|
||||||
offset += fSessionOffset;
|
if (error != B_OK)
|
||||||
if (read_pos(fDeviceFD, offset, pts, toRead) != toRead) {
|
return error;
|
||||||
#ifndef _BOOT_MODE
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PartitionMapWriter::_ReadBlock(off_t partitionOffset,
|
||||||
|
partition_table& partitionTable)
|
||||||
|
{
|
||||||
|
if (partitionOffset < 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
// TODO: If fBlockSize > sizeof(partition_table) then stop/read NULL after
|
||||||
|
if (read_pos(fDeviceFD, partitionOffset, &partitionTable, fBlockSize)
|
||||||
|
!= fBlockSize) {
|
||||||
status_t error = errno;
|
status_t error = errno;
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = B_IO_ERROR;
|
error = B_IO_ERROR;
|
||||||
#else
|
|
||||||
status_t error = B_IO_ERROR;
|
|
||||||
#endif
|
|
||||||
TRACE(("intel: _ReadSector(): reading the partition table failed: %lx\n",
|
|
||||||
error));
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,31 +260,19 @@ PartitionMapWriter::_ReadSector(off_t offset, partition_table* pts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _WriteSector
|
|
||||||
/*! \brief Writes the sector to the disk.
|
|
||||||
*/
|
|
||||||
status_t
|
status_t
|
||||||
PartitionMapWriter::_WriteSector(off_t offset, const partition_table* pts)
|
PartitionMapWriter::_WriteBlock(off_t partitionOffset,
|
||||||
|
const partition_table& partitionTable)
|
||||||
{
|
{
|
||||||
int32 toWrite = sizeof(partition_table);
|
if (partitionOffset < 0)
|
||||||
// same as SECTOR_SIZE actually
|
|
||||||
|
|
||||||
// check the offset
|
|
||||||
if (offset < 0 || offset + toWrite > fSessionSize) {
|
|
||||||
TRACE(("intel: _WriteSector(): bad offset: %Ld\n", offset));
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
// TODO: If fBlockSize > sizeof(partition_table) then stop/write NULL after
|
||||||
|
if (write_pos(fDeviceFD, partitionOffset, &partitionTable, fBlockSize)
|
||||||
offset += fSessionOffset;
|
!= fBlockSize) {
|
||||||
|
|
||||||
// write
|
|
||||||
if (write_pos(fDeviceFD, offset, pts, toWrite) != toWrite) {
|
|
||||||
status_t error = errno;
|
status_t error = errno;
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = B_IO_ERROR;
|
error = B_IO_ERROR;
|
||||||
|
|
||||||
TRACE(("intel: _WriteSector(): writing the partition table failed: "
|
|
||||||
"%lx\n", error));
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Tomas Kucera, kucerat@centrum.cz
|
* Tomas Kucera, kucerat@centrum.cz
|
||||||
|
* Bryce Groff, brycegroff@gmail.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -26,8 +27,12 @@
|
|||||||
|
|
||||||
class PartitionMap;
|
class PartitionMap;
|
||||||
class LogicalPartition;
|
class LogicalPartition;
|
||||||
|
class PrimaryPartition;
|
||||||
struct partition_table;
|
struct partition_table;
|
||||||
|
|
||||||
|
bool check_logical_location(const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Writer for "Intel" style partitions.
|
\brief Writer for "Intel" style partitions.
|
||||||
|
|
||||||
@@ -36,33 +41,32 @@ struct partition_table;
|
|||||||
class PartitionMapWriter {
|
class PartitionMapWriter {
|
||||||
public:
|
public:
|
||||||
PartitionMapWriter(int deviceFD,
|
PartitionMapWriter(int deviceFD,
|
||||||
off_t sessionOffset, off_t sessionSize);
|
uint32 blockSize);
|
||||||
~PartitionMapWriter();
|
~PartitionMapWriter();
|
||||||
|
|
||||||
status_t WriteMBR(const PartitionMap* map,
|
status_t WriteMBR(const PartitionMap* map,
|
||||||
bool clearSectors);
|
bool clearCode);
|
||||||
status_t WriteLogical(partition_table* pts,
|
status_t WriteLogical(const LogicalPartition* logical,
|
||||||
const LogicalPartition* partition);
|
const PrimaryPartition* primary,
|
||||||
status_t WriteExtendedHead(partition_table* pts,
|
bool clearCode);
|
||||||
const LogicalPartition* firstPartition);
|
status_t WriteExtendedHead(
|
||||||
|
const LogicalPartition* logical,
|
||||||
|
const PrimaryPartition* primary,
|
||||||
|
bool clearCode);
|
||||||
|
|
||||||
|
status_t ClearExtendedHead(
|
||||||
|
const PrimaryPartition* primary);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _WritePrimary(partition_table* pts);
|
status_t _ReadBlock(off_t offset,
|
||||||
status_t _WriteExtended(partition_table* pts,
|
partition_table& partitionTable);
|
||||||
const LogicalPartition* partition,
|
status_t _WriteBlock(off_t offset,
|
||||||
const LogicalPartition* next);
|
const partition_table& partitionTable);
|
||||||
|
|
||||||
status_t _ReadSector(off_t offset,
|
|
||||||
partition_table* pts);
|
|
||||||
status_t _WriteSector(off_t offset,
|
|
||||||
const partition_table* pts);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fDeviceFD;
|
int fDeviceFD;
|
||||||
off_t fSessionOffset;
|
int32 fBlockSize;
|
||||||
off_t fSessionSize;
|
|
||||||
|
|
||||||
const PartitionMap* fMap; // while writing
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PARTITION_MAP_WRITER_H
|
#endif // PARTITION_MAP_WRITER_H
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
|
|||||||
|
|
||||||
// for logical partitions in Intel Extended Partition
|
// for logical partitions in Intel Extended Partition
|
||||||
// Count of free sectors after Partition Table Sector (at logical partition).
|
// Count of free sectors after Partition Table Sector (at logical partition).
|
||||||
static const uint32 FREE_SECTORS_AFTER_PTS = 0;
|
static const uint32 FREE_SECTORS_AFTER_PTS = 63;
|
||||||
// Count of free sectors after Master Boot Record.
|
// Count of free sectors after Master Boot Record.
|
||||||
static const uint32 FREE_SECTORS_AFTER_MBR = 0;
|
static const uint32 FREE_SECTORS_AFTER_MBR = 63;
|
||||||
// size of logical partition header in blocks
|
// size of logical partition header in blocks
|
||||||
static const uint32 PTS_OFFSET = FREE_SECTORS_AFTER_PTS + 1;
|
static const uint32 PTS_OFFSET = FREE_SECTORS_AFTER_PTS + 1;
|
||||||
static const uint32 MBR_OFFSET = FREE_SECTORS_AFTER_MBR + 1;
|
static const uint32 MBR_OFFSET = FREE_SECTORS_AFTER_MBR + 1;
|
||||||
@@ -448,15 +448,15 @@ pm_validate_set_type(partition_data *partition, const char *type)
|
|||||||
if (!partition || !type)
|
if (!partition || !type)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
partition_data *father = get_parent_partition(partition->id);
|
partition_data* parent = get_parent_partition(partition->id);
|
||||||
if (!father)
|
if (!parent)
|
||||||
return false;
|
return false;
|
||||||
PrimaryPartition* child = (PrimaryPartition*)partition->cookie;
|
PrimaryPartition* child = (PrimaryPartition*)partition->cookie;
|
||||||
if (!child)
|
if (!child)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// validity check of the type
|
// validity check of the type
|
||||||
return is_type_valid_pm(type, father, child);
|
return is_type_valid_pm(type, parent, child);
|
||||||
}
|
}
|
||||||
|
|
||||||
// pm_validate_initialize
|
// pm_validate_initialize
|
||||||
@@ -564,8 +564,8 @@ pm_validate_create_child(partition_data *partition, off_t *start, off_t *size,
|
|||||||
return false;
|
return false;
|
||||||
*index = newIndex;
|
*index = newIndex;
|
||||||
|
|
||||||
if (*start < partition->offset + MBR_OFFSET * SECTOR_SIZE) {
|
if (*start < partition->offset + MBR_OFFSET * partition->block_size) {
|
||||||
*start = partition->offset + MBR_OFFSET * SECTOR_SIZE;
|
*start = partition->offset + MBR_OFFSET * partition->block_size;
|
||||||
*start = sector_align_up(*start);
|
*start = sector_align_up(*start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,12 +658,11 @@ get_partitionable_spaces(partition_data *partition,
|
|||||||
|
|
||||||
// offset alignment (to upper bound)
|
// offset alignment (to upper bound)
|
||||||
offset = sector_align_up(offset);
|
offset = sector_align_up(offset);
|
||||||
|
|
||||||
// finding out all partitionable spaces
|
// finding out all partitionable spaces
|
||||||
for (int32 i = 0; i < partition_count; i++) {
|
for (int32 i = 0; i < partition_count; i++) {
|
||||||
size = positions[i].offset - offset;
|
size = positions[i].offset - offset;
|
||||||
size = sector_align(size);
|
size = sector_align(size);
|
||||||
if (size > limitSize) {
|
if (size >= limitSize) {
|
||||||
if (actualCount < count) {
|
if (actualCount < count) {
|
||||||
buffer[actualCount].offset = offset;
|
buffer[actualCount].offset = offset;
|
||||||
buffer[actualCount].size = size;
|
buffer[actualCount].size = size;
|
||||||
@@ -714,7 +713,7 @@ pm_get_partitionable_spaces(partition_data *partition,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return get_partitionable_spaces(partition, buffer, count, actualCount,
|
return get_partitionable_spaces(partition, buffer, count, actualCount,
|
||||||
fill_partitionable_spaces_buffer_pm, MBR_OFFSET * SECTOR_SIZE,
|
fill_partitionable_spaces_buffer_pm, MBR_OFFSET * partition->block_size,
|
||||||
0, 0);
|
0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -994,7 +993,7 @@ pm_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||||||
primary->SetSize(validatedSize);
|
primary->SetSize(validatedSize);
|
||||||
|
|
||||||
// TODO: The partition is not supposed to be locked here!
|
// TODO: The partition is not supposed to be locked here!
|
||||||
PartitionMapWriter writer(fd, 0, partition->size);
|
PartitionMapWriter writer(fd, primary->BlockSize());
|
||||||
// TODO: disk size?
|
// TODO: disk size?
|
||||||
status_t error = writer.WriteMBR(map, false);
|
status_t error = writer.WriteMBR(map, false);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
@@ -1151,7 +1150,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
|
|
||||||
// buffer allocation
|
// buffer allocation
|
||||||
int32 allocated;
|
int32 allocated;
|
||||||
uint8 *buffer = allocate_buffer(SECTOR_SIZE, MAX_MOVE_BUFFER,
|
uint8* buffer = allocate_buffer(partition->block_size, MAX_MOVE_BUFFER,
|
||||||
&allocated);
|
&allocated);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -1161,7 +1160,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
update_disk_device_job_progress(job, 0.0);
|
update_disk_device_job_progress(job, 0.0);
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
error = move_partition(fd, child->offset, validatedOffset, child->size,
|
error = move_partition(fd, child->offset, validatedOffset, child->size,
|
||||||
buffer, allocated * SECTOR_SIZE, job);
|
buffer, allocated * partition->block_size, job);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
@@ -1171,7 +1170,7 @@ pm_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
child->offset = validatedOffset;
|
child->offset = validatedOffset;
|
||||||
primary->SetOffset(validatedOffset);
|
primary->SetOffset(validatedOffset);
|
||||||
|
|
||||||
PartitionMapWriter writer(fd, 0, partition->size);
|
PartitionMapWriter writer(fd, partition->block_size);
|
||||||
// TODO: disk size?
|
// TODO: disk size?
|
||||||
error = writer.WriteMBR(map, false);
|
error = writer.WriteMBR(map, false);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
@@ -1230,7 +1229,7 @@ pm_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||||||
primary->SetType(ptype.Type());
|
primary->SetType(ptype.Type());
|
||||||
|
|
||||||
// TODO: The partition is not supposed to be locked at this point!
|
// TODO: The partition is not supposed to be locked at this point!
|
||||||
PartitionMapWriter writer(fd, 0, partition->size);
|
PartitionMapWriter writer(fd, primary->BlockSize());
|
||||||
// TODO: disk size?
|
// TODO: disk size?
|
||||||
status_t error = writer.WriteMBR(map, false);
|
status_t error = writer.WriteMBR(map, false);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
@@ -1261,13 +1260,21 @@ pm_initialize(int fd, partition_id partitionID, const char *name,
|
|||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
PartitionWriteLocker locker(partitionID);
|
||||||
|
if (!locker.IsLocked())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// get partition and partition map structure
|
||||||
|
partition_data* partition = get_partition(partitionID);
|
||||||
|
if (!partition)
|
||||||
|
return B_BAD_VALUE;
|
||||||
update_disk_device_job_progress(job, 0.0);
|
update_disk_device_job_progress(job, 0.0);
|
||||||
|
|
||||||
// we will write an empty partition map
|
// we will write an empty partition map
|
||||||
PartitionMap map;
|
PartitionMap map;
|
||||||
|
|
||||||
// write the sector to disk
|
// write the sector to disk
|
||||||
PartitionMapWriter writer(fd, 0, partitionSize);
|
PartitionMapWriter writer(fd, partition->block_size);
|
||||||
// TODO: disk size or 2 * SECTOR_SIZE?
|
// TODO: disk size or 2 * SECTOR_SIZE?
|
||||||
status_t error = writer.WriteMBR(&map, true);
|
status_t error = writer.WriteMBR(&map, true);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
@@ -1345,6 +1352,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
bool active = get_driver_boolean_parameter(handle, "active", false, true);
|
bool active = get_driver_boolean_parameter(handle, "active", false, true);
|
||||||
|
delete_driver_settings(handle);
|
||||||
|
|
||||||
// set the active flags to false
|
// set the active flags to false
|
||||||
if (active) {
|
if (active) {
|
||||||
@@ -1361,8 +1369,8 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
primary->SetActive(active);
|
primary->SetActive(active);
|
||||||
|
|
||||||
// write changes to disk
|
// write changes to disk
|
||||||
PartitionMapWriter writer(fd, 0, partition->size);
|
PartitionMapWriter writer(fd, primary->BlockSize());
|
||||||
// TODO: disk size or 2 * SECTOR_SIZE?
|
|
||||||
// TODO: The partition is not supposed to be locked at this point!
|
// TODO: The partition is not supposed to be locked at this point!
|
||||||
status_t error = writer.WriteMBR(map, false);
|
status_t error = writer.WriteMBR(map, false);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
@@ -1374,7 +1382,7 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
|
|
||||||
*childID = child->id;
|
*childID = child->id;
|
||||||
|
|
||||||
child->block_size = SECTOR_SIZE;
|
child->block_size = primary->BlockSize();
|
||||||
// (no name)
|
// (no name)
|
||||||
child->type = strdup(type);
|
child->type = strdup(type);
|
||||||
// parameters
|
// parameters
|
||||||
@@ -1384,6 +1392,14 @@ pm_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
if (!child->type || !child->parameters)
|
if (!child->type || !child->parameters)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
// rescan partition if needed
|
||||||
|
if (strcmp(type, INTEL_EXTENDED_PARTITION_NAME) == 0) {
|
||||||
|
writer.ClearExtendedHead(primary);
|
||||||
|
error = scan_partition(partitionID);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// all changes applied
|
// all changes applied
|
||||||
update_disk_device_job_progress(job, 1.0);
|
update_disk_device_job_progress(job, 1.0);
|
||||||
partition_modified(partitionID);
|
partition_modified(partitionID);
|
||||||
@@ -1422,7 +1438,7 @@ pm_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
primary->Unset();
|
primary->Unset();
|
||||||
|
|
||||||
// write changes to disk
|
// write changes to disk
|
||||||
PartitionMapWriter writer(fd, 0, partition->size);
|
PartitionMapWriter writer(fd, primary->BlockSize());
|
||||||
// TODO: disk size or 2 * SECTOR_SIZE?
|
// TODO: disk size or 2 * SECTOR_SIZE?
|
||||||
// TODO: The partition is not supposed to be locked at this point!
|
// TODO: The partition is not supposed to be locked at this point!
|
||||||
status_t error = writer.WriteMBR(map, false);
|
status_t error = writer.WriteMBR(map, false);
|
||||||
@@ -1458,7 +1474,7 @@ ep_get_supported_operations(partition_data* partition, uint32 mask)
|
|||||||
|
|
||||||
// creating child
|
// creating child
|
||||||
int32 countSpaces = 0;
|
int32 countSpaces = 0;
|
||||||
if (pm_get_partitionable_spaces(partition, NULL, 0, &countSpaces)
|
if (ep_get_partitionable_spaces(partition, NULL, 0, &countSpaces)
|
||||||
== B_BUFFER_OVERFLOW
|
== B_BUFFER_OVERFLOW
|
||||||
&& countSpaces > 0) {
|
&& countSpaces > 0) {
|
||||||
flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD;
|
flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD;
|
||||||
@@ -1635,21 +1651,20 @@ ep_validate_create_child(partition_data *partition, off_t *_start, off_t *_size,
|
|||||||
|
|
||||||
// finding out index of the new partition (it will be the last child)
|
// finding out index of the new partition (it will be the last child)
|
||||||
*index = partition->child_count;
|
*index = partition->child_count;
|
||||||
|
|
||||||
// validate position
|
// validate position
|
||||||
off_t diffOffset = PTS_OFFSET * SECTOR_SIZE;
|
off_t start = *_start + FREE_SECTORS_AFTER_PTS * partition->block_size;
|
||||||
off_t start = *_start - diffOffset;
|
off_t size = *_size - FREE_SECTORS_AFTER_PTS * partition->block_size;
|
||||||
off_t size = *_size + diffOffset;
|
if (start < partition->offset + FREE_SECTORS_AFTER_PTS * partition->block_size) {
|
||||||
if (start < partition->offset + PTS_OFFSET * SECTOR_SIZE) {
|
start = partition->offset + FREE_SECTORS_AFTER_PTS * partition->block_size;
|
||||||
start = partition->offset + PTS_OFFSET * SECTOR_SIZE;
|
|
||||||
start = sector_align_up(start);
|
start = sector_align_up(start);
|
||||||
}
|
}
|
||||||
if (!validate_create_child_partition(partition, &start, &size,
|
if (!validate_create_child_partition(partition, &start, &size,
|
||||||
get_sibling_partitions_ep)) {
|
get_sibling_partitions_ep)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*_start = start + diffOffset;
|
|
||||||
*_size = size - diffOffset;
|
*_start = start;
|
||||||
|
*_size = size;
|
||||||
if (*_size == 0)
|
if (*_size == 0)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@@ -1673,9 +1688,9 @@ ep_get_partitionable_spaces(partition_data *partition,
|
|||||||
|
|
||||||
return get_partitionable_spaces(partition, buffer, count, actualCount,
|
return get_partitionable_spaces(partition, buffer, count, actualCount,
|
||||||
fill_partitionable_spaces_buffer_ep,
|
fill_partitionable_spaces_buffer_ep,
|
||||||
partition->offset + PTS_OFFSET * SECTOR_SIZE,
|
partition->offset + PTS_OFFSET * partition->block_size,
|
||||||
PTS_OFFSET * SECTOR_SIZE,
|
PTS_OFFSET * partition->block_size,
|
||||||
PTS_OFFSET * SECTOR_SIZE);
|
PTS_OFFSET * partition->block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1795,7 +1810,8 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||||||
if (!partition || !child)
|
if (!partition || !child)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
||||||
if (!logical)
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
|
if (!logical || !primary)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// validate the new size
|
// validate the new size
|
||||||
@@ -1810,17 +1826,17 @@ ep_resize_child(int fd, partition_id partitionID, off_t size, disk_job_id job)
|
|||||||
update_disk_device_job_progress(job, 0.0);
|
update_disk_device_job_progress(job, 0.0);
|
||||||
logical->SetSize(validatedSize);
|
logical->SetSize(validatedSize);
|
||||||
|
|
||||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
PartitionMapWriter writer(fd, partition->block_size);
|
||||||
// TODO: The partition is not supposed to be locked here!
|
// TODO: The partition is not supposed to be locked here!
|
||||||
status_t error = writer.WriteLogical(NULL, logical);
|
status_t error = writer.WriteLogical(logical, primary, false);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
// putting into previous state
|
// putting into previous state
|
||||||
logical->SetSize(child->size);
|
logical->SetSize(child->size);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
LogicalPartition* prev = logical->Previous();
|
LogicalPartition* prev = logical->Previous();
|
||||||
error = prev ? writer.WriteLogical(NULL, prev)
|
error = prev ? writer.WriteLogical(prev, primary, false)
|
||||||
: writer.WriteExtendedHead(NULL, logical);
|
: writer.WriteLogical(logical, primary, false);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
// this should be not so fatal
|
// this should be not so fatal
|
||||||
return error;
|
return error;
|
||||||
@@ -1882,7 +1898,8 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
if (!partition || !child)
|
if (!partition || !child)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
||||||
if (!logical)
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
|
if (!logical || !primary)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// TODO: The parameter has already been checked and must not be altered!
|
// TODO: The parameter has already been checked and must not be altered!
|
||||||
@@ -1898,7 +1915,8 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
|
|
||||||
// buffer allocation
|
// buffer allocation
|
||||||
int32 allocated;
|
int32 allocated;
|
||||||
uint8 *buffer = allocate_buffer(SECTOR_SIZE, MAX_MOVE_BUFFER, &allocated);
|
uint8* buffer = allocate_buffer(partition->block_size, MAX_MOVE_BUFFER,
|
||||||
|
&allocated);
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -1909,7 +1927,7 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
off_t pts_offset = logical->Offset() - logical->PartitionTableOffset();
|
off_t pts_offset = logical->Offset() - logical->PartitionTableOffset();
|
||||||
error = move_partition(fd, child->offset - pts_offset,
|
error = move_partition(fd, child->offset - pts_offset,
|
||||||
validatedOffset - pts_offset, child->size + pts_offset, buffer,
|
validatedOffset - pts_offset, child->size + pts_offset, buffer,
|
||||||
allocated * SECTOR_SIZE, job);
|
allocated * partition->block_size, job);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
@@ -1920,18 +1938,18 @@ ep_move_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
logical->SetOffset(logical->Offset() + diffOffset);
|
logical->SetOffset(logical->Offset() + diffOffset);
|
||||||
logical->SetPartitionTableOffset(logical->PartitionTableOffset() + diffOffset);
|
logical->SetPartitionTableOffset(logical->PartitionTableOffset() + diffOffset);
|
||||||
|
|
||||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
PartitionMapWriter writer(fd, partition->block_size);
|
||||||
// TODO: If partition->offset is > prev->offset, then writing
|
// TODO: If partition->offset is > prev->offset, then writing
|
||||||
// the previous logical partition table will fail!
|
// the previous logical partition table will fail!
|
||||||
// TODO: The partition is not supposed to be locked here!
|
// TODO: The partition is not supposed to be locked here!
|
||||||
error = writer.WriteLogical(NULL, logical);
|
error = writer.WriteLogical(logical, primary, false);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
// something went wrong - this is fatal (partition has been moved)
|
// something went wrong - this is fatal (partition has been moved)
|
||||||
// but EBR is not updated
|
// but EBR is not updated
|
||||||
return error;
|
return error;
|
||||||
LogicalPartition* prev = logical->Previous();
|
LogicalPartition* prev = logical->Previous();
|
||||||
error = prev ? writer.WriteLogical(NULL, prev)
|
error = prev ? writer.WriteLogical(prev, primary, false)
|
||||||
: writer.WriteExtendedHead(NULL, logical);
|
: writer.WriteLogical(logical, primary, false);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
// this is fatal - linked list is not updated
|
// this is fatal - linked list is not updated
|
||||||
return error;
|
return error;
|
||||||
@@ -1962,7 +1980,8 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||||||
if (!partition || !child)
|
if (!partition || !child)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
||||||
if (!logical)
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
|
if (!logical || !primary)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// TODO: The parameter has already been checked and must not be altered!
|
// TODO: The parameter has already been checked and must not be altered!
|
||||||
@@ -1984,9 +2003,9 @@ ep_set_type(int fd, partition_id partitionID, const char *type, disk_job_id job)
|
|||||||
uint8 oldType = logical->Type();
|
uint8 oldType = logical->Type();
|
||||||
logical->SetType(ptype.Type());
|
logical->SetType(ptype.Type());
|
||||||
|
|
||||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
PartitionMapWriter writer(fd, partition->block_size);
|
||||||
// TODO: The partition is not supposed to be locked here!
|
// TODO: The partition is not supposed to be locked here!
|
||||||
status_t error = writer.WriteLogical(NULL, logical);
|
status_t error = writer.WriteLogical(logical, primary, false);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
// something went wrong - putting into previous state
|
// something went wrong - putting into previous state
|
||||||
logical->SetType(oldType);
|
logical->SetType(oldType);
|
||||||
@@ -2021,7 +2040,8 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
|
|||||||
|
|
||||||
// get partition
|
// get partition
|
||||||
partition_data* partition = get_partition(partitionID);
|
partition_data* partition = get_partition(partitionID);
|
||||||
if (!partition)
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
|
if (!partition || !primary)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// name is ignored - we cannot set it to the Intel Extended Partition
|
// name is ignored - we cannot set it to the Intel Extended Partition
|
||||||
@@ -2031,7 +2051,6 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
|
|||||||
|
|
||||||
// partition init (we have no child partition)
|
// partition init (we have no child partition)
|
||||||
update_disk_device_job_progress(job, 0.0);
|
update_disk_device_job_progress(job, 0.0);
|
||||||
PrimaryPartition *primary = (PrimaryPartition*)partition->cookie;
|
|
||||||
// fill in the partition_data structure
|
// fill in the partition_data structure
|
||||||
partition->status = B_PARTITION_VALID;
|
partition->status = B_PARTITION_VALID;
|
||||||
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM;
|
partition->flags |= B_PARTITION_PARTITIONING_SYSTEM;
|
||||||
@@ -2044,9 +2063,9 @@ ep_initialize(int fd, partition_id partitionID, const char *name,
|
|||||||
partition_table table;
|
partition_table table;
|
||||||
table.clear_code_area();
|
table.clear_code_area();
|
||||||
|
|
||||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
PartitionMapWriter writer(fd, partition->block_size);
|
||||||
// TODO: The partition is not supposed to be locked here!
|
// TODO: The partition is not supposed to be locked here!
|
||||||
status_t error = writer.WriteExtendedHead(&table, NULL);
|
status_t error = writer.ClearExtendedHead(primary);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -2076,25 +2095,22 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
if (!locker.IsLocked())
|
if (!locker.IsLocked())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
// get parent, partition and PrimaryPartition structure
|
|
||||||
partition_data *parent = get_parent_partition(partitionID);
|
|
||||||
partition_data* partition = get_partition(partitionID);
|
partition_data* partition = get_partition(partitionID);
|
||||||
if (!parent || !partition)
|
partition_data* device = get_parent_partition(partitionID);
|
||||||
|
if (partition == NULL || device == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
if (!primary)
|
if (!primary)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
// validate the offset, size and get index of the new partition
|
// validate the offset, size and get index of the new partition
|
||||||
// TODO: The parameter has already been checked and must not be altered!
|
|
||||||
off_t validatedOffset = offset;
|
off_t validatedOffset = offset;
|
||||||
off_t validatedSize = size;
|
off_t validatedSize = size;
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
if (!ep_validate_create_child(partition, &validatedOffset, &validatedSize,
|
if (!ep_validate_create_child(partition, &validatedOffset, &validatedSize,
|
||||||
type, name, parameters, &index)) {
|
type, name, parameters, &index))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
|
||||||
|
|
||||||
LogicalPartition* logical = new(nothrow) LogicalPartition;
|
LogicalPartition* logical = new(nothrow) LogicalPartition;
|
||||||
if (!logical)
|
if (!logical)
|
||||||
@@ -2104,54 +2120,60 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
update_disk_device_job_progress(job, 0.0);
|
update_disk_device_job_progress(job, 0.0);
|
||||||
partition_data* child = create_child_partition(partition->id, index,
|
partition_data* child = create_child_partition(partition->id, index,
|
||||||
validatedOffset, validatedSize, *childID);
|
validatedOffset, validatedSize, *childID);
|
||||||
if (!child) {
|
if (!child)
|
||||||
delete logical;
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
PartitionType ptype;
|
PartitionType ptype;
|
||||||
ptype.SetType(type);
|
ptype.SetType(type);
|
||||||
|
logical->SetPartitionTableOffset(
|
||||||
logical->SetPartitionTableOffset(validatedOffset - PTS_OFFSET * SECTOR_SIZE
|
validatedOffset - FREE_SECTORS_AFTER_PTS * partition->block_size);
|
||||||
- partition->offset);
|
logical->SetOffset(validatedOffset);
|
||||||
logical->SetOffset(validatedOffset - partition->offset);
|
|
||||||
logical->SetSize(validatedSize);
|
logical->SetSize(validatedSize);
|
||||||
logical->SetType(ptype.Type());
|
logical->SetType(ptype.Type());
|
||||||
// TODO: correctly fill active parameter
|
|
||||||
logical->SetActive(false);
|
logical->SetActive(false);
|
||||||
|
logical->SetPrimaryPartition(primary);
|
||||||
|
logical->SetBlockSize(partition->block_size);
|
||||||
|
primary->AddLogicalPartition(logical);
|
||||||
|
|
||||||
// we delete code area in EBR - nothing should be there
|
// If the table offset of this partition is supposed to be at the start
|
||||||
partition_table table;
|
// of the extended partition, but is not the first logical partition to
|
||||||
table.clear_code_area();
|
// be written, then increased the table offset by one block.
|
||||||
|
if (logical->PartitionTableOffset() == primary->Offset()
|
||||||
|
&& logical->Previous() != NULL) {
|
||||||
|
logical->SetPartitionTableOffset(logical->PartitionTableOffset()
|
||||||
|
+ logical->BlockSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
int deviceFD = open_partition(device->id, O_RDWR);
|
||||||
|
if (deviceFD < 0)
|
||||||
|
return B_IO_ERROR;
|
||||||
|
|
||||||
// write changes to disk
|
// write changes to disk
|
||||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
PartitionMapWriter writer(deviceFD, primary->BlockSize());
|
||||||
// TODO: wrong offset range, writing prev will fail
|
// Write the logical partition's EBR first in case of failure.
|
||||||
|
// This way we will not add a partition to the previous logical
|
||||||
|
// partition. If there is no previous logical partition then write
|
||||||
|
// the current partition's EBR to the first sector of the primary partition
|
||||||
|
|
||||||
// TODO: The partition is not supposed to be locked here!
|
status_t error = writer.WriteLogical(logical, primary, true);
|
||||||
status_t error = writer.WriteLogical(&table, logical);
|
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
// putting into previous state
|
|
||||||
delete_partition(child->id);
|
|
||||||
delete logical;
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
// update linked list
|
|
||||||
primary->AddLogicalPartition(logical);
|
|
||||||
LogicalPartition *prev = logical->Previous();
|
|
||||||
error = prev ? writer.WriteLogical(NULL, prev)
|
|
||||||
: writer.WriteExtendedHead(NULL, logical);
|
|
||||||
if (error != B_OK) {
|
|
||||||
// putting into previous state
|
|
||||||
delete_partition(child->id);
|
|
||||||
primary->RemoveLogicalPartition(logical);
|
primary->RemoveLogicalPartition(logical);
|
||||||
delete logical;
|
delete logical;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LogicalPartition* previous = logical->Previous();
|
||||||
|
if (previous != NULL) {
|
||||||
|
error = writer.WriteLogical(previous, primary, true);
|
||||||
|
if (error != B_OK) {
|
||||||
|
primary->RemoveLogicalPartition(logical);
|
||||||
|
delete logical;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
*childID = child->id;
|
*childID = child->id;
|
||||||
|
|
||||||
child->block_size = SECTOR_SIZE;
|
child->block_size = logical->BlockSize();
|
||||||
// (no name)
|
// (no name)
|
||||||
child->type = strdup(type);
|
child->type = strdup(type);
|
||||||
// parameters
|
// parameters
|
||||||
@@ -2183,34 +2205,42 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
partition_data* partition = get_partition(partitionID);
|
partition_data* partition = get_partition(partitionID);
|
||||||
|
partition_data* device = get_parent_partition(partitionID);
|
||||||
partition_data* child = get_partition(childID);
|
partition_data* child = get_partition(childID);
|
||||||
if (!partition || !child)
|
if (partition == NULL || device == NULL || child == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
LogicalPartition* logical = (LogicalPartition*)child->cookie;
|
||||||
if (!primary || !logical)
|
if (primary == NULL || logical == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
|
||||||
// deleting child
|
// deleting child
|
||||||
update_disk_device_job_progress(job, 0.0);
|
update_disk_device_job_progress(job, 0.0);
|
||||||
if (!delete_partition(childID))
|
if (!delete_partition(childID))
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
LogicalPartition *next_logical = logical->Next();
|
LogicalPartition* previous = logical->Previous();
|
||||||
LogicalPartition *prev_logical = logical->Previous();
|
LogicalPartition* next = logical->Next();
|
||||||
|
|
||||||
primary->RemoveLogicalPartition(logical);
|
primary->RemoveLogicalPartition(logical);
|
||||||
delete logical;
|
delete logical;
|
||||||
|
|
||||||
|
int deviceFD = open_partition(device->id, O_RDWR);
|
||||||
|
if (deviceFD < 0)
|
||||||
|
return B_IO_ERROR;
|
||||||
|
|
||||||
// write changes to disk
|
// write changes to disk
|
||||||
PartitionMapWriter writer(fd, partition->offset, partition->size);
|
PartitionMapWriter writer(deviceFD, primary->BlockSize());
|
||||||
// TODO: Check offset range! Writing "prev/next_logical"?
|
|
||||||
// Should be parent->offset and parent->size?
|
status_t error = previous ? writer.WriteLogical(previous, primary, true)
|
||||||
// TODO: The partition is not supposed to be locked here!
|
: writer.WriteExtendedHead(next, primary, true);
|
||||||
status_t error = prev_logical ? writer.WriteLogical(NULL, prev_logical)
|
|
||||||
: writer.WriteExtendedHead(NULL, next_logical);
|
if (error != B_OK) {
|
||||||
if (error != B_OK)
|
delete logical;
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// all changes applied
|
// all changes applied
|
||||||
update_disk_device_job_progress(job, 1.0);
|
update_disk_device_job_progress(job, 1.0);
|
||||||
|
|||||||
@@ -154,6 +154,22 @@ get_child_partition(partition_id partitionID, int32 index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
open_partition(partition_id partitionID, int openMode)
|
||||||
|
{
|
||||||
|
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||||
|
KPartition *partition = manager->FindPartition(partitionID);
|
||||||
|
if (partition == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
int fd = -1;
|
||||||
|
status_t result = partition->Open(openMode, &fd);
|
||||||
|
if (result != B_OK)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
// create_child_partition
|
// create_child_partition
|
||||||
partition_data *
|
partition_data *
|
||||||
create_child_partition(partition_id partitionID, int32 index, off_t offset,
|
create_child_partition(partition_id partitionID, int32 index, off_t offset,
|
||||||
|
|||||||
Reference in New Issue
Block a user