The info about partitionable space will be provided by the userland disk
system add-ons. First work to make this class usable for them. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22539 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -12,25 +12,35 @@ struct partitionable_space_data;
|
|||||||
|
|
||||||
class BPartitioningInfo {
|
class BPartitioningInfo {
|
||||||
public:
|
public:
|
||||||
BPartitioningInfo();
|
BPartitioningInfo();
|
||||||
virtual ~BPartitioningInfo();
|
virtual ~BPartitioningInfo();
|
||||||
|
|
||||||
void Unset();
|
status_t SetTo(off_t offset, off_t size);
|
||||||
|
void Unset();
|
||||||
|
|
||||||
partition_id PartitionID() const;
|
status_t ExcludeOccupiedSpace(off_t offset,
|
||||||
|
off_t size);
|
||||||
|
|
||||||
status_t GetPartitionableSpaceAt(int32 index, off_t *offset,
|
// TODO: We don't need the partition ID.
|
||||||
off_t *size) const;
|
partition_id PartitionID() const;
|
||||||
int32 CountPartitionableSpaces() const;
|
|
||||||
|
status_t GetPartitionableSpaceAt(int32 index,
|
||||||
|
off_t* offset, off_t*size) const;
|
||||||
|
int32 CountPartitionableSpaces() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _SetTo(partition_id partition, int32 changeCounter);
|
status_t _SetTo(partition_id partition,
|
||||||
|
int32 changeCounter);
|
||||||
|
|
||||||
|
status_t _InsertSpaces(int32 index, int32 count);
|
||||||
|
void _RemoveSpaces(int32 index, int32 count);
|
||||||
|
|
||||||
friend class BPartition;
|
friend class BPartition;
|
||||||
|
|
||||||
partition_id fPartitionID;
|
partition_id fPartitionID;
|
||||||
partitionable_space_data *fSpaces;
|
partitionable_space_data* fSpaces;
|
||||||
int32 fCount;
|
int32 fCount;
|
||||||
|
int32 fCapacity;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _PARTITIONING_INFO_H
|
#endif // _PARTITIONING_INFO_H
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
// by the OpenBeOS license.
|
// by the OpenBeOS license.
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
#include <PartitioningInfo.h>
|
#include <PartitioningInfo.h>
|
||||||
@@ -10,22 +12,53 @@
|
|||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
#include <disk_device_manager/ddm_userland_interface.h>
|
#include <disk_device_manager/ddm_userland_interface.h>
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
BPartitioningInfo::BPartitioningInfo()
|
BPartitioningInfo::BPartitioningInfo()
|
||||||
: fPartitionID(-1),
|
: fPartitionID(-1),
|
||||||
fSpaces(NULL),
|
fSpaces(NULL),
|
||||||
fCount(0)
|
fCount(0),
|
||||||
|
fCapacity(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
BPartitioningInfo::~BPartitioningInfo()
|
BPartitioningInfo::~BPartitioningInfo()
|
||||||
{
|
{
|
||||||
Unset();
|
Unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SetTo
|
||||||
|
status_t
|
||||||
|
BPartitioningInfo::SetTo(off_t offset, off_t size)
|
||||||
|
{
|
||||||
|
fPartitionID = -1;
|
||||||
|
delete[] fSpaces;
|
||||||
|
|
||||||
|
if (size > 0) {
|
||||||
|
fSpaces = new(nothrow) partitionable_space_data[1];
|
||||||
|
if (!fSpaces)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fCount = 1;
|
||||||
|
fSpaces[0].offset = offset;
|
||||||
|
fSpaces[0].size = size;
|
||||||
|
} else {
|
||||||
|
fSpaces = NULL;
|
||||||
|
fCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fCapacity = fCount;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Unset
|
// Unset
|
||||||
void
|
void
|
||||||
BPartitioningInfo::Unset()
|
BPartitioningInfo::Unset()
|
||||||
@@ -34,8 +67,80 @@ BPartitioningInfo::Unset()
|
|||||||
fPartitionID = -1;
|
fPartitionID = -1;
|
||||||
fSpaces = NULL;
|
fSpaces = NULL;
|
||||||
fCount = 0;
|
fCount = 0;
|
||||||
|
fCapacity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ExcludeOccupiedSpace
|
||||||
|
status_t
|
||||||
|
BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size)
|
||||||
|
{
|
||||||
|
if (size <= 0)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
int32 leftIndex = -1;
|
||||||
|
int32 rightIndex = -1;
|
||||||
|
for (int32 i = 0; i < fCount; i++) {
|
||||||
|
if (leftIndex == -1
|
||||||
|
&& offset < fSpaces[i].offset + fSpaces[i].size) {
|
||||||
|
leftIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fSpaces[i].offset < offset + size)
|
||||||
|
rightIndex = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there's no intersection with any free space, we're done.
|
||||||
|
if (leftIndex == -1 || rightIndex == -1 || leftIndex > rightIndex)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
|
partitionable_space_data& leftSpace = fSpaces[leftIndex];
|
||||||
|
partitionable_space_data& rightSpace = fSpaces[rightIndex];
|
||||||
|
|
||||||
|
off_t rightSpaceEnd = rightSpace.offset + rightSpace.size;
|
||||||
|
|
||||||
|
// special case: split a single space in two
|
||||||
|
if (leftIndex == rightIndex && leftSpace.offset < offset
|
||||||
|
&& rightSpaceEnd > offset + size) {
|
||||||
|
// add a space after this one
|
||||||
|
status_t error = _InsertSpaces(leftIndex + 1, 1);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
partitionable_space_data& space = fSpaces[leftIndex];
|
||||||
|
partitionable_space_data& newSpace = fSpaces[leftIndex + 1];
|
||||||
|
|
||||||
|
space.size = offset - space.offset;
|
||||||
|
|
||||||
|
newSpace.offset = offset + size;
|
||||||
|
newSpace.size = rightSpaceEnd - newSpace.offset;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether the first affected space is eaten completely
|
||||||
|
int32 deleteFirst = leftIndex;
|
||||||
|
if (leftSpace.offset < offset) {
|
||||||
|
leftSpace.size = offset - leftSpace.offset;
|
||||||
|
deleteFirst++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether the last affected space is eaten completely
|
||||||
|
int32 deleteLast = rightIndex;
|
||||||
|
if (rightSpaceEnd > offset + size) {
|
||||||
|
rightSpace.offset = offset + size;
|
||||||
|
rightSpace.size = rightSpaceEnd - rightSpace.offset;
|
||||||
|
deleteLast--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove all spaces that are completely eaten
|
||||||
|
if (deleteFirst <= deleteLast)
|
||||||
|
_RemoveSpaces(deleteFirst, deleteLast - deleteFirst + 1);
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// PartitionID
|
// PartitionID
|
||||||
partition_id
|
partition_id
|
||||||
BPartitioningInfo::PartitionID() const
|
BPartitioningInfo::PartitionID() const
|
||||||
@@ -43,6 +148,7 @@ BPartitioningInfo::PartitionID() const
|
|||||||
return fPartitionID;
|
return fPartitionID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetPartitionableSpaceAt
|
// GetPartitionableSpaceAt
|
||||||
status_t
|
status_t
|
||||||
BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset,
|
BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset,
|
||||||
@@ -55,6 +161,7 @@ BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset,
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// CountPartitionableSpaces
|
// CountPartitionableSpaces
|
||||||
int32
|
int32
|
||||||
BPartitioningInfo::CountPartitionableSpaces() const
|
BPartitioningInfo::CountPartitionableSpaces() const
|
||||||
@@ -62,6 +169,7 @@ BPartitioningInfo::CountPartitionableSpaces() const
|
|||||||
return fCount;
|
return fCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _SetTo
|
// _SetTo
|
||||||
status_t
|
status_t
|
||||||
BPartitioningInfo::_SetTo(partition_id partition, int32 changeCounter)
|
BPartitioningInfo::_SetTo(partition_id partition, int32 changeCounter)
|
||||||
@@ -100,3 +208,55 @@ BPartitioningInfo::_SetTo(partition_id partition, int32 changeCounter)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _InsertSpaces
|
||||||
|
status_t
|
||||||
|
BPartitioningInfo::_InsertSpaces(int32 index, int32 count)
|
||||||
|
{
|
||||||
|
if (index <= 0 || index > fCount || count <= 0)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// If the capacity is sufficient, we just need to copy the spaces to create
|
||||||
|
// a gap.
|
||||||
|
if (fCount + count <= fCapacity) {
|
||||||
|
memmove(fSpaces + index + count, fSpaces + index, fCount - index);
|
||||||
|
fCount += count;
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// alloc new array
|
||||||
|
int32 capacity = (fCount + count) * 2;
|
||||||
|
// add a bit room for further resizing
|
||||||
|
|
||||||
|
partitionable_space_data* spaces
|
||||||
|
= new(nothrow) partitionable_space_data[capacity];
|
||||||
|
if (!spaces)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
// copy items
|
||||||
|
memcpy(spaces, fSpaces, index);
|
||||||
|
memcpy(spaces + index + count, fSpaces + index, fCount - index);
|
||||||
|
|
||||||
|
delete[] fSpaces;
|
||||||
|
fSpaces = spaces;
|
||||||
|
fCapacity = capacity;
|
||||||
|
fCount += count;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _RemoveSpaces
|
||||||
|
void
|
||||||
|
BPartitioningInfo::_RemoveSpaces(int32 index, int32 count)
|
||||||
|
{
|
||||||
|
if (index <= 0 || count <= 0 || index + count > fCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (count < fCount) {
|
||||||
|
int32 endIndex = index + count;
|
||||||
|
memmove(fSpaces + index, fSpaces + endIndex, fCount - endIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
fCount -= count;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user