* Added parameter passing to/from the kernel to userland.
* Removed dependency on deprecated ep_validate_create_child() * Removed hard coded sector size. * Style cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32590 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -339,6 +339,7 @@ ep_scan_partition(int fd, partition_data* partition, void* cookie)
|
|||||||
partition_data* parent = get_parent_partition(partition->id);
|
partition_data* parent = get_parent_partition(partition->id);
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
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;
|
||||||
@@ -372,8 +373,9 @@ ep_scan_partition(int fd, partition_data* partition, void* cookie)
|
|||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
sprintf(buffer, "type = %u ; active = %d", logical->Type(),
|
sprintf(buffer, "active %s ;\npartition_table_offset %lld ;\n",
|
||||||
logical->Active());
|
logical->Active() ? "true" : "false",
|
||||||
|
logical->PartitionTableOffset());
|
||||||
child->parameters = strdup(buffer);
|
child->parameters = strdup(buffer);
|
||||||
child->cookie = logical;
|
child->cookie = logical;
|
||||||
// check for allocation problems
|
// check for allocation problems
|
||||||
|
|||||||
@@ -32,9 +32,6 @@
|
|||||||
//#define TRACE(x) ;
|
//#define TRACE(x) ;
|
||||||
#define TRACE(x) dprintf x
|
#define TRACE(x) dprintf x
|
||||||
|
|
||||||
// TODO: get rid of this - there is no such thing as a fixed sector size!
|
|
||||||
static const uint32 SECTOR_SIZE = 512;
|
|
||||||
|
|
||||||
// Maximal size of move buffer (in sectors).
|
// Maximal size of move buffer (in sectors).
|
||||||
static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
|
static const int32 MAX_MOVE_BUFFER = 2 * 1024 * 4;
|
||||||
|
|
||||||
@@ -111,23 +108,38 @@ pm_is_sub_system_for(partition_data* partition)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
get_partition_from_offset_ep(partition_data* partition, off_t offset,
|
||||||
|
partition_data** nextPartition)
|
||||||
|
{
|
||||||
|
for (int32 i = 0; i < partition->child_count; i++) {
|
||||||
|
partition_data* sibling = get_child_partition(partition->id, i);
|
||||||
|
if (sibling != NULL && sibling->offset == offset) {
|
||||||
|
*nextPartition = sibling;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Intel Partition Map - validate functions
|
// #pragma mark - Intel Partition Map - validate functions
|
||||||
|
|
||||||
|
|
||||||
// sector_align (auxiliary function)
|
// sector_align (auxiliary function)
|
||||||
static inline off_t
|
static inline off_t
|
||||||
sector_align(off_t offset)
|
sector_align(off_t offset, int32 blockSize)
|
||||||
{
|
{
|
||||||
return offset / SECTOR_SIZE * SECTOR_SIZE;
|
return offset / blockSize * blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// sector_align_up (auxiliary function)
|
// sector_align_up (auxiliary function)
|
||||||
static inline off_t
|
static inline off_t
|
||||||
sector_align_up(off_t offset)
|
sector_align_up(off_t offset, int32 blockSize)
|
||||||
{
|
{
|
||||||
return (offset + SECTOR_SIZE - 1) / SECTOR_SIZE * SECTOR_SIZE;
|
return (offset + blockSize - 1) / blockSize * blockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -143,7 +155,7 @@ validate_resize(partition_data* partition, off_t* size)
|
|||||||
if (newSize < 0)
|
if (newSize < 0)
|
||||||
newSize = 0;
|
newSize = 0;
|
||||||
else
|
else
|
||||||
newSize = sector_align(newSize);
|
newSize = sector_align(newSize, partition->block_size);
|
||||||
|
|
||||||
// grow partition?
|
// grow partition?
|
||||||
if (newSize > partition->size) {
|
if (newSize > partition->size) {
|
||||||
@@ -163,7 +175,7 @@ validate_resize(partition_data* partition, off_t* size)
|
|||||||
}
|
}
|
||||||
newSize = currentEnd - partition->offset;
|
newSize = currentEnd - partition->offset;
|
||||||
// make the size a multiple of the block size (greater one)
|
// make the size a multiple of the block size (greater one)
|
||||||
newSize = sector_align_up(newSize);
|
newSize = sector_align_up(newSize, partition->block_size);
|
||||||
*size = newSize;
|
*size = newSize;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -182,26 +194,6 @@ pm_validate_resize(partition_data* partition, off_t* size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// get_offset_ep (auxiliary function)
|
|
||||||
static inline off_t
|
|
||||||
get_offset_ep(const partition_data* partition)
|
|
||||||
{
|
|
||||||
LogicalPartition *logical = (LogicalPartition *)partition->cookie;
|
|
||||||
off_t diff_offset = logical->Offset() - logical->PartitionTableOffset();
|
|
||||||
return partition->offset - diff_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// get_size_ep (auxiliary function)
|
|
||||||
static inline off_t
|
|
||||||
get_size_ep(const partition_data* partition)
|
|
||||||
{
|
|
||||||
LogicalPartition *logical = (LogicalPartition *)partition->cookie;
|
|
||||||
off_t diff_offset = logical->Offset() - logical->PartitionTableOffset();
|
|
||||||
return partition->size + diff_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// get_sibling_partitions_pm (auxiliary function)
|
// get_sibling_partitions_pm (auxiliary function)
|
||||||
/*!
|
/*!
|
||||||
according to childOffset returns previous and next sibling or NULL
|
according to childOffset returns previous and next sibling or NULL
|
||||||
@@ -261,7 +253,7 @@ get_sibling_partitions_ep(partition_data* partition,
|
|||||||
for (int32 i = 0; i < partition->child_count; i++) {
|
for (int32 i = 0; i < partition->child_count; i++) {
|
||||||
partition_data* sibling = get_child_partition(partition->id, i);
|
partition_data* sibling = get_child_partition(partition->id, i);
|
||||||
if (sibling && sibling != child) {
|
if (sibling && sibling != child) {
|
||||||
if (get_offset_ep(sibling) <= childOffset) {
|
if (sibling->offset <= childOffset) {
|
||||||
if (!previousSibling || previousSibling->offset < sibling->offset)
|
if (!previousSibling || previousSibling->offset < sibling->offset)
|
||||||
previousSibling = sibling;
|
previousSibling = sibling;
|
||||||
} else {
|
} else {
|
||||||
@@ -274,12 +266,12 @@ get_sibling_partitions_ep(partition_data* partition,
|
|||||||
*previous = previousSibling;
|
*previous = previousSibling;
|
||||||
*next = nextSibling;
|
*next = nextSibling;
|
||||||
if (previousSibling) {
|
if (previousSibling) {
|
||||||
*previousOffset = get_offset_ep(previousSibling);
|
*previousOffset = previousSibling->offset;
|
||||||
*previousSize = get_size_ep(previousSibling);
|
*previousSize = previousSibling->size;
|
||||||
}
|
}
|
||||||
if (nextSibling) {
|
if (nextSibling) {
|
||||||
*nextOffset = get_offset_ep(nextSibling);
|
*nextOffset = nextSibling->offset;
|
||||||
*nextSize = get_size_ep(nextSibling);
|
*nextSize = nextSibling->size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,7 +290,7 @@ validate_resize_child(partition_data* partition, partition_data* child,
|
|||||||
if (*size < 0)
|
if (*size < 0)
|
||||||
*size = 0;
|
*size = 0;
|
||||||
// make the size a multiple of the block size
|
// make the size a multiple of the block size
|
||||||
*size = sector_align(*size);
|
*size = sector_align(*size, partition->block_size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// grow partition
|
// grow partition
|
||||||
@@ -317,7 +309,7 @@ validate_resize_child(partition_data* partition, partition_data* child,
|
|||||||
|
|
||||||
if (nextSibling && (nextOffset < childOffset + *size))
|
if (nextSibling && (nextOffset < childOffset + *size))
|
||||||
*size = nextOffset - childOffset;
|
*size = nextOffset - childOffset;
|
||||||
*size = sector_align(*size);
|
*size = sector_align(*size, partition->block_size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,7 +355,7 @@ validate_move_child(partition_data* partition, partition_data* child,
|
|||||||
else if (start + childSize > partition->size)
|
else if (start + childSize > partition->size)
|
||||||
start = partition->size - childSize;
|
start = partition->size - childSize;
|
||||||
|
|
||||||
start = sector_align(start);
|
start = sector_align(start, partition->block_size);
|
||||||
|
|
||||||
// finding out sibling partitions
|
// finding out sibling partitions
|
||||||
partition_data* previousSibling = NULL;
|
partition_data* previousSibling = NULL;
|
||||||
@@ -378,13 +370,13 @@ validate_move_child(partition_data* partition, partition_data* child,
|
|||||||
// moving left
|
// moving left
|
||||||
if (previousSibling && previousOffset + previousSize > start) {
|
if (previousSibling && previousOffset + previousSize > start) {
|
||||||
start = previousOffset + previousSize;
|
start = previousOffset + previousSize;
|
||||||
start = sector_align_up(start);
|
start = sector_align_up(start, partition->block_size);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// moving right
|
// moving right
|
||||||
if (nextSibling && nextOffset < start + childSize) {
|
if (nextSibling && nextOffset < start + childSize) {
|
||||||
start = nextOffset - childSize;
|
start = nextOffset - childSize;
|
||||||
start = sector_align(start);
|
start = sector_align(start, partition->block_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*_start = start;
|
*_start = start;
|
||||||
@@ -487,11 +479,11 @@ validate_create_child_partition(partition_data* partition, off_t* start,
|
|||||||
off_t* size, fc_get_sibling_partitions getSiblingPartitions)
|
off_t* size, fc_get_sibling_partitions getSiblingPartitions)
|
||||||
{
|
{
|
||||||
// make the start and size a multiple of the block size
|
// make the start and size a multiple of the block size
|
||||||
*start = sector_align(*start);
|
*start = sector_align(*start, partition->block_size);
|
||||||
if (*size < 0)
|
if (*size < 0)
|
||||||
*size = 0;
|
*size = 0;
|
||||||
else
|
else
|
||||||
*size = sector_align(*size);
|
*size = sector_align(*size, partition->block_size);
|
||||||
|
|
||||||
// child must completely lie within the parent partition
|
// child must completely lie within the parent partition
|
||||||
if (*start >= partition->offset + partition->size)
|
if (*start >= partition->offset + partition->size)
|
||||||
@@ -511,12 +503,12 @@ validate_create_child_partition(partition_data* partition, off_t* start,
|
|||||||
// position check of the new partition
|
// position check of the new partition
|
||||||
if (previousSibling && (previousOffset + previousSize > *start)) {
|
if (previousSibling && (previousOffset + previousSize > *start)) {
|
||||||
*start = previousOffset + previousSize;
|
*start = previousOffset + previousSize;
|
||||||
*start = sector_align_up(*start);
|
*start = sector_align_up(*start, partition->block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextSibling && (nextOffset < *start + *size))
|
if (nextSibling && (nextOffset < *start + *size))
|
||||||
*size = nextOffset - *start;
|
*size = nextOffset - *start;
|
||||||
*size = sector_align(*size);
|
*size = sector_align(*size, partition->block_size);
|
||||||
if (*size == 0)
|
if (*size == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -566,7 +558,7 @@ pm_validate_create_child(partition_data* partition, off_t* start, off_t* size,
|
|||||||
|
|
||||||
if (*start < partition->offset + MBR_OFFSET * partition->block_size) {
|
if (*start < partition->offset + MBR_OFFSET * partition->block_size) {
|
||||||
*start = partition->offset + MBR_OFFSET * partition->block_size;
|
*start = partition->offset + MBR_OFFSET * partition->block_size;
|
||||||
*start = sector_align_up(*start);
|
*start = sector_align_up(*start, partition->block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return validate_create_child_partition(partition, start, size,
|
return validate_create_child_partition(partition, start, size,
|
||||||
@@ -625,8 +617,8 @@ fill_partitionable_spaces_buffer_ep(partition_data* partition,
|
|||||||
for (int32 i = 0; i < partition->child_count; i++) {
|
for (int32 i = 0; i < partition->child_count; i++) {
|
||||||
const partition_data* child = get_child_partition(partition->id, i);
|
const partition_data* child = get_child_partition(partition->id, i);
|
||||||
if (child) {
|
if (child) {
|
||||||
positions[partition_count].offset = get_offset_ep(child);
|
positions[partition_count].offset = child->offset;
|
||||||
positions[partition_count].size = get_size_ep(child);
|
positions[partition_count].size = child->size;
|
||||||
partition_count++;
|
partition_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -657,11 +649,11 @@ get_partitionable_spaces(partition_data* partition,
|
|||||||
int32 actualCount = 0;
|
int32 actualCount = 0;
|
||||||
|
|
||||||
// offset alignment (to upper bound)
|
// offset alignment (to upper bound)
|
||||||
offset = sector_align_up(offset);
|
offset = sector_align_up(offset, partition->block_size);
|
||||||
// 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, partition->block_size);
|
||||||
if (size >= limitSize) {
|
if (size >= limitSize) {
|
||||||
if (actualCount < count) {
|
if (actualCount < count) {
|
||||||
buffer[actualCount].offset = offset;
|
buffer[actualCount].offset = offset;
|
||||||
@@ -670,11 +662,11 @@ get_partitionable_spaces(partition_data* partition,
|
|||||||
actualCount++;
|
actualCount++;
|
||||||
}
|
}
|
||||||
offset = positions[i].offset + positions[i].size + headerSize;
|
offset = positions[i].offset + positions[i].size + headerSize;
|
||||||
offset = sector_align_up(offset);
|
offset = sector_align_up(offset, partition->block_size);
|
||||||
}
|
}
|
||||||
// space in the end of partition
|
// space in the end of partition
|
||||||
size = partition->offset + partition->size - offset;
|
size = partition->offset + partition->size - offset;
|
||||||
size = sector_align(size);
|
size = sector_align(size, partition->block_size);
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
if (actualCount < count) {
|
if (actualCount < count) {
|
||||||
buffer[actualCount].offset = offset;
|
buffer[actualCount].offset = offset;
|
||||||
@@ -1541,12 +1533,11 @@ ep_validate_resize_child(partition_data* partition, partition_data* child,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// validate position
|
// validate position
|
||||||
off_t diff_offset = child->offset - get_offset_ep(child);
|
off_t size = *_size;
|
||||||
off_t size = *_size + diff_offset;
|
if (!validate_resize_child(partition, child, child->offset,
|
||||||
if (!validate_resize_child(partition, child, get_offset_ep(child),
|
child->size, &size, get_sibling_partitions_ep))
|
||||||
get_size_ep(child), &size, get_sibling_partitions_ep))
|
|
||||||
return false;
|
return false;
|
||||||
*_size = size - diff_offset;
|
*_size = size;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1577,12 +1568,11 @@ ep_validate_move_child(partition_data* partition, partition_data* child,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// validate position
|
// validate position
|
||||||
off_t diff_offset = child->offset - get_offset_ep(child);
|
off_t start = *_start;
|
||||||
off_t start = *_start - diff_offset;
|
if (!validate_move_child(partition, child, child->offset,
|
||||||
if (!validate_move_child(partition, child, get_offset_ep(child),
|
child->size, &start, get_sibling_partitions_ep))
|
||||||
get_size_ep(child), &start, get_sibling_partitions_ep))
|
|
||||||
return false;
|
return false;
|
||||||
*_start = start + diff_offset;
|
*_start = start;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1632,44 +1622,13 @@ ep_validate_initialize(partition_data* partition, char* name,
|
|||||||
|
|
||||||
// ep_validate_create_child
|
// ep_validate_create_child
|
||||||
bool
|
bool
|
||||||
ep_validate_create_child(partition_data* partition, off_t* _start, off_t* _size,
|
ep_validate_create_child(partition_data* partition, off_t* offset, off_t* size,
|
||||||
const char* type, const char* name, const char* parameters, int32* index)
|
const char* type, const char* name, const char* parameters, int32* index)
|
||||||
// index - returns position of the new partition (the last one)
|
// index - returns position of the new partition (the last one)
|
||||||
{
|
{
|
||||||
TRACE(("intel: ep_validate_create_child\n"));
|
|
||||||
|
|
||||||
if (!partition || !(ep_get_supported_operations(partition)
|
|
||||||
& B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD)
|
|
||||||
|| !_start || !_size || !type || !index) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check parameters
|
|
||||||
// type check
|
|
||||||
if (!is_type_valid_ep(type))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// finding out index of the new partition (it will be the last child)
|
|
||||||
*index = partition->child_count;
|
|
||||||
// validate position
|
|
||||||
off_t start = *_start + FREE_SECTORS_AFTER_PTS * partition->block_size;
|
|
||||||
off_t size = *_size - FREE_SECTORS_AFTER_PTS * partition->block_size;
|
|
||||||
if (start < partition->offset + FREE_SECTORS_AFTER_PTS * partition->block_size) {
|
|
||||||
start = partition->offset + FREE_SECTORS_AFTER_PTS * partition->block_size;
|
|
||||||
start = sector_align_up(start);
|
|
||||||
}
|
|
||||||
if (!validate_create_child_partition(partition, &start, &size,
|
|
||||||
get_sibling_partitions_ep)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
*_start = start;
|
|
||||||
*_size = size;
|
|
||||||
if (*_size == 0)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ep_get_partitionable_spaces
|
// ep_get_partitionable_spaces
|
||||||
status_t
|
status_t
|
||||||
@@ -1750,6 +1709,45 @@ ep_shadow_changed(partition_data* partition, partition_data* child,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
check_partition_location_ep(partition_data* partition, off_t offset,
|
||||||
|
off_t size, off_t ptsOffset)
|
||||||
|
{
|
||||||
|
if (!partition)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// make sure we are sector aligned
|
||||||
|
off_t alignedOffset = sector_align(offset, partition->block_size);
|
||||||
|
if (alignedOffset != offset)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// partition does not lie within extended partition
|
||||||
|
if (offset < partition->offset
|
||||||
|
|| offset > partition->offset + partition->size
|
||||||
|
&& offset + size <= partition->offset + partition->size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check if the new partition table is within an existing partition
|
||||||
|
// or that the new partition does not overwrite an existing partition
|
||||||
|
// table.
|
||||||
|
for (int32 i = 0; i < partition->child_count; i++) {
|
||||||
|
partition_data* sibling = get_child_partition(partition->id, i);
|
||||||
|
LogicalPartition* logical = (LogicalPartition*)sibling->cookie;
|
||||||
|
if (logical == NULL)
|
||||||
|
return false;
|
||||||
|
if (ptsOffset > logical->Offset()
|
||||||
|
&& ptsOffset < logical->Offset() + logical->Size())
|
||||||
|
return false;
|
||||||
|
if (logical->PartitionTableOffset() >= offset
|
||||||
|
&& logical->PartitionTableOffset() < offset + size
|
||||||
|
|| logical->PartitionTableOffset() == ptsOffset)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - Intel Extended Partition - write functions
|
// #pragma mark - Intel Extended Partition - write functions
|
||||||
|
|
||||||
|
|
||||||
@@ -2091,70 +2089,80 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
if (fd < 0 || !childID)
|
if (fd < 0 || !childID)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// aquire lock
|
||||||
PartitionWriteLocker locker(partitionID);
|
PartitionWriteLocker locker(partitionID);
|
||||||
if (!locker.IsLocked())
|
if (!locker.IsLocked())
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
// get partition data
|
||||||
partition_data* partition = get_partition(partitionID);
|
partition_data* partition = get_partition(partitionID);
|
||||||
partition_data* device = get_parent_partition(partitionID);
|
partition_data* parent = get_parent_partition(partitionID);
|
||||||
if (partition == NULL || device == NULL)
|
if (partition == NULL || parent == 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
|
// parse parameters
|
||||||
off_t validatedOffset = offset;
|
void* handle = parse_driver_settings_string(parameters);
|
||||||
off_t validatedSize = size;
|
if (handle == NULL)
|
||||||
int32 index = 0;
|
return B_ERROR;
|
||||||
if (!ep_validate_create_child(partition, &validatedOffset, &validatedSize,
|
|
||||||
type, name, parameters, &index))
|
bool active = get_driver_boolean_parameter(handle, "active", false, true);
|
||||||
|
|
||||||
|
off_t ptsOffset = 0;
|
||||||
|
const char* buffer = get_driver_parameter(
|
||||||
|
handle, "partition_table_offset", NULL, NULL);
|
||||||
|
if (buffer != NULL)
|
||||||
|
ptsOffset = strtoull(buffer, NULL, 10);
|
||||||
|
else {
|
||||||
|
delete_driver_settings(handle);
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
delete_driver_settings(handle);
|
||||||
|
|
||||||
|
// check the partition location
|
||||||
|
if (!check_partition_location_ep(partition, offset, size, ptsOffset))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// creating partition
|
||||||
|
update_disk_device_job_progress(job, 0.0);
|
||||||
|
partition_data* child = create_child_partition(partition->id,
|
||||||
|
partition->child_count, offset, size, *childID);
|
||||||
|
if (!child)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// setup logical partition
|
||||||
LogicalPartition* logical = new(nothrow) LogicalPartition;
|
LogicalPartition* logical = new(nothrow) LogicalPartition;
|
||||||
if (!logical)
|
if (!logical)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
// creating partition
|
|
||||||
update_disk_device_job_progress(job, 0.0);
|
|
||||||
partition_data* child = create_child_partition(partition->id, index,
|
|
||||||
validatedOffset, validatedSize, *childID);
|
|
||||||
if (!child)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
PartitionType ptype;
|
PartitionType ptype;
|
||||||
ptype.SetType(type);
|
ptype.SetType(type);
|
||||||
logical->SetPartitionTableOffset(
|
logical->SetPartitionTableOffset(ptsOffset - parent->offset);
|
||||||
validatedOffset - FREE_SECTORS_AFTER_PTS * partition->block_size);
|
logical->SetOffset(offset);
|
||||||
logical->SetOffset(validatedOffset);
|
logical->SetSize(size);
|
||||||
logical->SetSize(validatedSize);
|
|
||||||
logical->SetType(ptype.Type());
|
logical->SetType(ptype.Type());
|
||||||
logical->SetActive(false);
|
logical->SetActive(active);
|
||||||
logical->SetPrimaryPartition(primary);
|
logical->SetPrimaryPartition(primary);
|
||||||
logical->SetBlockSize(partition->block_size);
|
logical->SetBlockSize(partition->block_size);
|
||||||
primary->AddLogicalPartition(logical);
|
primary->AddLogicalPartition(logical);
|
||||||
|
|
||||||
// If the table offset of this partition is supposed to be at the start
|
int parentFD = open_partition(parent->id, O_RDWR);
|
||||||
// of the extended partition, but is not the first logical partition to
|
if (parentFD < 0) {
|
||||||
// be written, then increased the table offset by one block.
|
primary->RemoveLogicalPartition(logical);
|
||||||
if (logical->PartitionTableOffset() == primary->Offset()
|
delete logical;
|
||||||
&& logical->Previous() != NULL) {
|
return B_IO_ERROR;
|
||||||
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(deviceFD, primary->BlockSize());
|
PartitionMapWriter writer(parentFD, primary->BlockSize());
|
||||||
|
|
||||||
// Write the logical partition's EBR first in case of failure.
|
// Write the logical partition's EBR first in case of failure.
|
||||||
// This way we will not add a partition to the previous logical
|
// This way we will not add a partition to the previous logical
|
||||||
// partition. If there is no previous logical partition then write
|
// partition. If there is no previous logical partition then write
|
||||||
// the current partition's EBR to the first sector of the primary partition
|
// the current partition's EBR to the first sector of the primary partition
|
||||||
|
|
||||||
status_t error = writer.WriteLogical(logical, primary, true);
|
status_t error = writer.WriteLogical(logical, primary, true);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
primary->RemoveLogicalPartition(logical);
|
primary->RemoveLogicalPartition(logical);
|
||||||
@@ -2174,9 +2182,7 @@ ep_create_child(int fd, partition_id partitionID, off_t offset, off_t size,
|
|||||||
*childID = child->id;
|
*childID = child->id;
|
||||||
|
|
||||||
child->block_size = logical->BlockSize();
|
child->block_size = logical->BlockSize();
|
||||||
// (no name)
|
|
||||||
child->type = strdup(type);
|
child->type = strdup(type);
|
||||||
// parameters
|
|
||||||
child->parameters = strdup(parameters);
|
child->parameters = strdup(parameters);
|
||||||
child->cookie = logical;
|
child->cookie = logical;
|
||||||
// check for allocation problems
|
// check for allocation problems
|
||||||
@@ -2205,9 +2211,9 @@ 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* parent = get_parent_partition(partitionID);
|
||||||
partition_data* child = get_partition(childID);
|
partition_data* child = get_partition(childID);
|
||||||
if (partition == NULL || device == NULL || child == NULL)
|
if (partition == NULL || parent == NULL || child == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
PrimaryPartition* primary = (PrimaryPartition*)partition->cookie;
|
||||||
@@ -2215,7 +2221,6 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
if (primary == NULL || logical == NULL)
|
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))
|
||||||
@@ -2227,15 +2232,35 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
primary->RemoveLogicalPartition(logical);
|
primary->RemoveLogicalPartition(logical);
|
||||||
delete logical;
|
delete logical;
|
||||||
|
|
||||||
int deviceFD = open_partition(device->id, O_RDWR);
|
int parentFD = open_partition(parent->id, O_RDWR);
|
||||||
if (deviceFD < 0)
|
if (parentFD < 0)
|
||||||
return B_IO_ERROR;
|
return B_IO_ERROR;
|
||||||
|
|
||||||
// write changes to disk
|
// write changes to disk
|
||||||
PartitionMapWriter writer(deviceFD, primary->BlockSize());
|
PartitionMapWriter writer(parentFD, primary->BlockSize());
|
||||||
|
|
||||||
status_t error = previous ? writer.WriteLogical(previous, primary, true)
|
status_t error;
|
||||||
: writer.WriteExtendedHead(next, primary, true);
|
if (previous != NULL) {
|
||||||
|
error = writer.WriteLogical(previous, primary, true);
|
||||||
|
} else {
|
||||||
|
error = writer.WriteExtendedHead(next, primary, true);
|
||||||
|
|
||||||
|
if (next != NULL) {
|
||||||
|
next->SetPartitionTableOffset(primary->Offset());
|
||||||
|
|
||||||
|
partition_data* nextSibling = NULL;
|
||||||
|
if (get_partition_from_offset_ep(partition, next->Offset(),
|
||||||
|
&nextSibling)) {
|
||||||
|
char buffer[128];
|
||||||
|
sprintf(buffer, "active %s ;\npartition_table_offset %lld ;\n",
|
||||||
|
next->Active() ? "true" : "false",
|
||||||
|
next->PartitionTableOffset());
|
||||||
|
nextSibling->parameters = strdup(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close(parentFD);
|
||||||
|
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
delete logical;
|
delete logical;
|
||||||
@@ -2247,3 +2272,4 @@ ep_delete_child(int fd, partition_id partitionID, partition_id childID,
|
|||||||
partition_modified(partitionID);
|
partition_modified(partitionID);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user