* The shadow_changed() FS and partitioning system hooks take an
additional partition_data* child parameter now. * _user_get_partitionable_spaces() doesn't need to copy the buffer into the kernel, since it is no input parameter. It also copies back the actual partitionable spaces count on error, now -- B_BUFFER_OVERFLOW is returned when the buffer was too small, but then the count must be returned too. * Fixed several instances of syscall implementations that unloaded a disk system, although they didn't load it in the first place. This screwed up the load count with undesirable consequences. * _user_create_child_partition() would set the size to the supplied offset. * Fixed broken loop in KPhysicalPartition::CreateShadowPartition(). * KPartition::RemoveChild() notified the listeners about the wrong event. * Intel partitioning module: - The *_get_partitionable_spaces() correctly return B_BUFFER_OVERFLOW now, if the supplied buffer is too small. - Implemented a part of pm_shadow_changed(), which creates and updates the PartitionMap, so that the validate_*() hooks have a chance to work at all. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22475 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a68ceab8df
commit
bf95c9aee6
@ -219,7 +219,7 @@ typedef struct file_system_module_info {
|
||||
|
||||
/* shadow partition modification (device is write locked) */
|
||||
status_t (*shadow_changed)(partition_data *partition,
|
||||
uint32 operation);
|
||||
partition_data *child, uint32 operation);
|
||||
|
||||
/* writing (the device is NOT locked) */
|
||||
status_t (*defragment)(int fd, partition_id partition,
|
||||
|
@ -257,7 +257,7 @@ typedef struct fssh_file_system_module_info {
|
||||
|
||||
/* shadow partition modification (device is write locked) */
|
||||
fssh_status_t (*shadow_changed)(fssh_partition_data *partition,
|
||||
uint32_t operation);
|
||||
fssh_partition_data *child, uint32_t operation);
|
||||
|
||||
/* writing (the device is NOT locked) */
|
||||
fssh_status_t (*defragment)(int fd, fssh_partition_id partition,
|
||||
|
@ -100,7 +100,7 @@ public:
|
||||
// Device must be write locked.
|
||||
|
||||
virtual status_t ShadowPartitionChanged(KPartition *partition,
|
||||
uint32 operation);
|
||||
KPartition *child, uint32 operation);
|
||||
|
||||
// Writing
|
||||
// Device should not be locked.
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
// Shadow partition modification
|
||||
|
||||
virtual status_t ShadowPartitionChanged(KPartition *partition,
|
||||
uint32 operation);
|
||||
KPartition *child, uint32 operation);
|
||||
|
||||
// Writing
|
||||
|
||||
|
@ -74,7 +74,7 @@ public:
|
||||
// Shadow partition modification
|
||||
|
||||
virtual status_t ShadowPartitionChanged(KPartition *partition,
|
||||
uint32 operation);
|
||||
KPartition *child, uint32 operation);
|
||||
|
||||
// Writing
|
||||
|
||||
|
@ -68,7 +68,8 @@ typedef struct partition_module_info {
|
||||
|
||||
// shadow partition modification
|
||||
// (device is write locked)
|
||||
status_t (*shadow_changed)(partition_data* partition, uint32 operation);
|
||||
status_t (*shadow_changed)(partition_data* partition,
|
||||
partition_data *child, uint32 operation);
|
||||
|
||||
|
||||
// writing
|
||||
|
@ -386,17 +386,6 @@ PrimaryPartition::PrimaryPartition()
|
||||
{
|
||||
}
|
||||
|
||||
// constructor
|
||||
PrimaryPartition::PrimaryPartition(const partition_descriptor *descriptor,
|
||||
off_t ptsOffset)
|
||||
: Partition(),
|
||||
fHead(NULL),
|
||||
fTail(NULL),
|
||||
fLogicalPartitionCount(0)
|
||||
{
|
||||
SetTo(descriptor, ptsOffset);
|
||||
}
|
||||
|
||||
// SetTo
|
||||
void
|
||||
PrimaryPartition::SetTo(const partition_descriptor *descriptor, off_t ptsOffset)
|
||||
@ -419,6 +408,34 @@ PrimaryPartition::Unset()
|
||||
Partition::Unset();
|
||||
}
|
||||
|
||||
|
||||
// Assign
|
||||
status_t
|
||||
PrimaryPartition::Assign(const PrimaryPartition& other)
|
||||
{
|
||||
partition_descriptor descriptor;
|
||||
other.GetPartitionDescriptor(&descriptor, 0);
|
||||
SetTo(&descriptor, 0);
|
||||
|
||||
const LogicalPartition* otherLogical = other.fHead;
|
||||
while (otherLogical) {
|
||||
off_t ptsOffset = otherLogical->PTSOffset();
|
||||
otherLogical->GetPartitionDescriptor(&descriptor, ptsOffset);
|
||||
|
||||
LogicalPartition* logical = new(nothrow) LogicalPartition(
|
||||
&descriptor, ptsOffset, this);
|
||||
if (!logical)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
AddLogicalPartition(logical);
|
||||
|
||||
otherLogical = otherLogical->Next();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// LogicalPartitionAt
|
||||
LogicalPartition *
|
||||
PrimaryPartition::LogicalPartitionAt(int32 index) const
|
||||
@ -527,6 +544,8 @@ LogicalPartition::Unset()
|
||||
// constructor
|
||||
PartitionMap::PartitionMap()
|
||||
{
|
||||
for (int32 i = 0; i < 4; i++)
|
||||
fPrimaries[i].SetIndex(i);
|
||||
}
|
||||
|
||||
// destructor
|
||||
@ -542,6 +561,21 @@ PartitionMap::Unset()
|
||||
fPrimaries[i].Unset();
|
||||
}
|
||||
|
||||
|
||||
// Assign
|
||||
status_t
|
||||
PartitionMap::Assign(const PartitionMap& other)
|
||||
{
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
status_t error = fPrimaries[i].Assign(other.fPrimaries[i]);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
// PrimaryPartitionAt
|
||||
PrimaryPartition *
|
||||
PartitionMap::PrimaryPartitionAt(int32 index)
|
||||
@ -562,6 +596,7 @@ PartitionMap::PrimaryPartitionAt(int32 index) const
|
||||
return partition;
|
||||
}
|
||||
|
||||
|
||||
// CountPartitions
|
||||
int32
|
||||
PartitionMap::CountPartitions() const
|
||||
|
@ -165,11 +165,16 @@ private:
|
||||
class PrimaryPartition : public Partition {
|
||||
public:
|
||||
PrimaryPartition();
|
||||
PrimaryPartition(const partition_descriptor *descriptor, off_t ptsOffset);
|
||||
|
||||
void SetTo(const partition_descriptor *descriptor, off_t ptsOffset);
|
||||
void Unset();
|
||||
|
||||
status_t Assign(const PrimaryPartition& other);
|
||||
|
||||
int32 Index() const { return fIndex; }
|
||||
void SetIndex(int32 index) { fIndex = index; }
|
||||
// private
|
||||
|
||||
// only if extended
|
||||
int32 CountLogicalPartitions() const { return fLogicalPartitionCount; }
|
||||
LogicalPartition *LogicalPartitionAt(int32 index) const;
|
||||
@ -180,6 +185,7 @@ private:
|
||||
LogicalPartition *fHead;
|
||||
LogicalPartition *fTail;
|
||||
int32 fLogicalPartitionCount;
|
||||
int32 fIndex;
|
||||
};
|
||||
|
||||
// LogicalPartition
|
||||
@ -216,8 +222,11 @@ public:
|
||||
|
||||
void Unset();
|
||||
|
||||
status_t Assign(const PartitionMap& other);
|
||||
|
||||
PrimaryPartition *PrimaryPartitionAt(int32 index);
|
||||
const PrimaryPartition *PrimaryPartitionAt(int32 index) const;
|
||||
int32 IndexOfPrimaryPartition(const PrimaryPartition* partition) const;
|
||||
|
||||
int32 CountPartitions() const;
|
||||
int32 CountNonEmptyPartitions() const;
|
||||
|
@ -131,7 +131,6 @@ pm_identify_partition(int fd, partition_data *partition, void **cookie)
|
||||
PartitionMapCookie *map = new(nothrow) PartitionMapCookie;
|
||||
if (!map)
|
||||
return -1;
|
||||
map->ref_count = 1;
|
||||
|
||||
// read the partition structure
|
||||
PartitionMapParser parser(fd, 0, partition->size);
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
// A PartitionMap with reference count.
|
||||
struct PartitionMapCookie : PartitionMap {
|
||||
PartitionMapCookie() : ref_count(1) {}
|
||||
|
||||
int32 ref_count;
|
||||
};
|
||||
|
||||
|
@ -77,7 +77,8 @@ pm_get_supported_operations(partition_data* partition, uint32 mask = ~0)
|
||||
int32 countSpaces = 0;
|
||||
if (partition->child_count < 4
|
||||
// free space check
|
||||
&& pm_get_partitionable_spaces(partition, NULL, 0, &countSpaces) == B_OK
|
||||
&& pm_get_partitionable_spaces(partition, NULL, 0, &countSpaces)
|
||||
== B_BUFFER_OVERFLOW
|
||||
&& countSpaces > 0) {
|
||||
flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD;
|
||||
}
|
||||
@ -661,8 +662,12 @@ get_partitionable_spaces(partition_data *partition,
|
||||
if (positions)
|
||||
delete[] positions;
|
||||
|
||||
*_actualCount = actualCount;
|
||||
TRACE(("intel: get_partitionable_spaces - found: %ld\n", actualCount));
|
||||
|
||||
*_actualCount = actualCount;
|
||||
|
||||
if (count < actualCount)
|
||||
return B_BUFFER_OVERFLOW;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@ -725,15 +730,162 @@ pm_get_next_supported_type(partition_data *partition, int32 *cookie,
|
||||
|
||||
// pm_shadow_changed
|
||||
status_t
|
||||
pm_shadow_changed(partition_data *partition, uint32 operation)
|
||||
pm_shadow_changed(partition_data *partition, partition_data *child,
|
||||
uint32 operation)
|
||||
{
|
||||
TRACE(("intel: pm_shadow_changed\n"));
|
||||
TRACE(("intel: pm_shadow_changed(%p, %p, %lu)\n", partition, child,
|
||||
operation));
|
||||
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
switch (operation) {
|
||||
case B_PARTITION_SHADOW:
|
||||
{
|
||||
// get the physical partition
|
||||
partition_data* physicalPartition = get_physical_partition(
|
||||
partition->id);
|
||||
if (!physicalPartition) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW): no "
|
||||
"physical partition with ID %ld\n", partition->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// nothing to do here
|
||||
return B_OK;
|
||||
// clone the map
|
||||
if (!physicalPartition->content_cookie) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW): no "
|
||||
"content cookie, physical partition: %ld\n", partition->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
PartitionMapCookie* map = new(nothrow) PartitionMapCookie;
|
||||
if (!map)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
status_t error = map->Assign(
|
||||
*(PartitionMapCookie*)physicalPartition->content_cookie);
|
||||
if (error != B_OK) {
|
||||
delete map;
|
||||
return error;
|
||||
}
|
||||
|
||||
partition->content_cookie = map;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_PARTITION_SHADOW_CHILD:
|
||||
{
|
||||
// get the physical child partition
|
||||
partition_data* physical = get_physical_partition(child->id);
|
||||
if (!physical) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): "
|
||||
"no physical partition with ID %ld\n", child->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (!physical->cookie) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): "
|
||||
"no cookie, physical partition: %ld\n", child->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// primary partition index
|
||||
int32 index = ((PrimaryPartition*)physical->cookie)->Index();
|
||||
|
||||
if (!partition->content_cookie) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): "
|
||||
"no content cookie, physical partition: %ld\n",
|
||||
partition->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// get the primary partition
|
||||
PartitionMapCookie* map
|
||||
= ((PartitionMapCookie*)partition->content_cookie);
|
||||
PrimaryPartition* primary = map->PrimaryPartitionAt(index);
|
||||
|
||||
if (!primary || primary->IsEmpty()) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_SHADOW_CHILD): "
|
||||
"partition %ld is empty, primary index: %ld\n", child->id,
|
||||
index);
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
child->cookie = primary;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_PARTITION_INITIALIZE:
|
||||
{
|
||||
// create an empty partition map
|
||||
PartitionMapCookie* map = new(nothrow) PartitionMapCookie;
|
||||
if (!map)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
partition->content_cookie = map;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_PARTITION_CREATE_CHILD:
|
||||
{
|
||||
if (!partition->content_cookie) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_CREATE_CHILD): "
|
||||
"no content cookie, partition: %ld\n", partition->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
PartitionMapCookie* map
|
||||
= ((PartitionMapCookie*)partition->content_cookie);
|
||||
|
||||
// find an empty primary partition slot
|
||||
PrimaryPartition* primary = NULL;
|
||||
for (int32 i = 0; i < 4; i++) {
|
||||
if (map->PrimaryPartitionAt(i)->IsEmpty()) {
|
||||
primary = map->PrimaryPartitionAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!primary) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_CREATE_CHILD): "
|
||||
"no empty primary slot, partition: %ld\n", partition->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// apply type
|
||||
PartitionType type;
|
||||
type.SetType(child->type);
|
||||
if (!type.IsValid()) {
|
||||
dprintf("intel: pm_shadow_changed(B_PARTITION_CREATE_CHILD): "
|
||||
"invalid partition type, partition: %ld\n", partition->id);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
primary->SetType(type.Type());
|
||||
|
||||
// TODO: Apply parameters!
|
||||
|
||||
child->cookie = primary;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
case B_PARTITION_DEFRAGMENT:
|
||||
case B_PARTITION_REPAIR:
|
||||
case B_PARTITION_RESIZE:
|
||||
case B_PARTITION_RESIZE_CHILD:
|
||||
case B_PARTITION_MOVE:
|
||||
case B_PARTITION_MOVE_CHILD:
|
||||
case B_PARTITION_SET_NAME:
|
||||
case B_PARTITION_SET_CONTENT_NAME:
|
||||
case B_PARTITION_SET_TYPE:
|
||||
case B_PARTITION_SET_PARAMETERS:
|
||||
case B_PARTITION_SET_CONTENT_PARAMETERS:
|
||||
case B_PARTITION_DELETE_CHILD:
|
||||
break;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@ -1249,7 +1401,8 @@ ep_get_supported_operations(partition_data* partition, uint32 mask = ~0)
|
||||
|
||||
// creating child
|
||||
int32 countSpaces = 0;
|
||||
if (pm_get_partitionable_spaces(partition, NULL, 0, &countSpaces) == B_OK
|
||||
if (pm_get_partitionable_spaces(partition, NULL, 0, &countSpaces)
|
||||
== B_BUFFER_OVERFLOW
|
||||
&& countSpaces > 0) {
|
||||
flags |= B_DISK_SYSTEM_SUPPORTS_CREATING_CHILD;
|
||||
}
|
||||
@ -1500,7 +1653,8 @@ ep_get_next_supported_type(partition_data *partition, int32 *cookie,
|
||||
|
||||
// ep_shadow_changed
|
||||
status_t
|
||||
ep_shadow_changed(partition_data *partition, uint32 operation)
|
||||
ep_shadow_changed(partition_data *partition, partition_data *child,
|
||||
uint32 operation)
|
||||
{
|
||||
TRACE(("intel: ep_shadow_changed\n"));
|
||||
|
||||
|
@ -33,7 +33,8 @@ status_t pm_get_partitionable_spaces(partition_data *partition,
|
||||
int32 *actualCount);
|
||||
status_t pm_get_next_supported_type(partition_data *partition, int32 *cookie,
|
||||
char *_type);
|
||||
status_t pm_shadow_changed(partition_data *partition, uint32 operation);
|
||||
status_t pm_shadow_changed(partition_data *partition, partition_data *child,
|
||||
uint32 operation);
|
||||
|
||||
status_t pm_resize(int fd, partition_id partitionID, off_t size,
|
||||
disk_job_id job);
|
||||
@ -77,7 +78,8 @@ status_t ep_get_partitionable_spaces(partition_data *partition,
|
||||
int32 *actualCount);
|
||||
status_t ep_get_next_supported_type(partition_data *partition, int32 *cookie,
|
||||
char *_type);
|
||||
status_t ep_shadow_changed(partition_data *partition, uint32 operation);
|
||||
status_t ep_shadow_changed(partition_data *partition, partition_data *child,
|
||||
uint32 operation);
|
||||
|
||||
status_t ep_resize(int fd, partition_id partitionID, off_t size,
|
||||
disk_job_id job);
|
||||
|
@ -118,6 +118,7 @@ status_t
|
||||
KDiskSystem::Load()
|
||||
{
|
||||
ManagerLocker locker(KDiskDeviceManager::Default());
|
||||
dprintf("KDiskSystem::Load(): %s -> %ld\n", Name(), fLoadCounter + 1);
|
||||
status_t error = B_OK;
|
||||
if (fLoadCounter == 0)
|
||||
error = LoadModule();
|
||||
@ -132,6 +133,7 @@ void
|
||||
KDiskSystem::Unload()
|
||||
{
|
||||
ManagerLocker locker(KDiskDeviceManager::Default());
|
||||
dprintf("KDiskSystem::Unload(): %s -> %ld\n", Name(), fLoadCounter - 1);
|
||||
if (fLoadCounter > 0 && --fLoadCounter == 0)
|
||||
UnloadModule();
|
||||
}
|
||||
@ -361,7 +363,8 @@ KDiskSystem::GetNextSupportedType(KPartition *partition, int32 *cookie,
|
||||
|
||||
// ShadowPartitionChanged
|
||||
status_t
|
||||
KDiskSystem::ShadowPartitionChanged(KPartition *partition, uint32 operation)
|
||||
KDiskSystem::ShadowPartitionChanged(KPartition *partition, KPartition *child,
|
||||
uint32 operation)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
@ -173,7 +173,8 @@ KFileSystem::ValidateInitialize(KPartition *partition, char *name,
|
||||
|
||||
// ShadowPartitionChanged
|
||||
status_t
|
||||
KFileSystem::ShadowPartitionChanged(KPartition *partition, uint32 operation)
|
||||
KFileSystem::ShadowPartitionChanged(KPartition *partition, KPartition *child,
|
||||
uint32 operation)
|
||||
{
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
@ -183,7 +184,8 @@ KFileSystem::ShadowPartitionChanged(KPartition *partition, uint32 operation)
|
||||
// make any additional changes.
|
||||
if (!fModule->shadow_changed)
|
||||
return B_OK;
|
||||
return fModule->shadow_changed(partition->PartitionData(), operation);
|
||||
return fModule->shadow_changed(partition->PartitionData(),
|
||||
child ? child->PartitionData() : NULL, operation);
|
||||
}
|
||||
|
||||
|
||||
|
@ -680,7 +680,7 @@ KPartition::RemoveChild(int32 index)
|
||||
partition->SetParent(NULL);
|
||||
partition->SetDevice(NULL);
|
||||
// notify listeners
|
||||
FireChildAdded(partition, index);
|
||||
FireChildRemoved(partition, index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -408,7 +408,7 @@ KPartitioningSystem::GetTypeForContentType(const char *contentType, char *type)
|
||||
//! Calls for additional modifications when shadow partition is changed
|
||||
status_t
|
||||
KPartitioningSystem::ShadowPartitionChanged(KPartition *partition,
|
||||
uint32 operation)
|
||||
KPartition *child, uint32 operation)
|
||||
{
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
@ -418,7 +418,8 @@ KPartitioningSystem::ShadowPartitionChanged(KPartition *partition,
|
||||
// have to make any additional changes.
|
||||
if (!fModule->shadow_changed)
|
||||
return B_OK;
|
||||
return fModule->shadow_changed(partition->PartitionData(), operation);
|
||||
return fModule->shadow_changed(partition->PartitionData(),
|
||||
child ? child->PartitionData() : NULL, operation);
|
||||
}
|
||||
|
||||
|
||||
|
@ -167,27 +167,54 @@ KPhysicalPartition::CreateShadowPartition()
|
||||
{
|
||||
if (fShadowPartition)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
// create shadow partition
|
||||
fShadowPartition = new(nothrow) KShadowPartition(this);
|
||||
if (!fShadowPartition)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// make it known to the manager
|
||||
if (!manager->PartitionAdded(fShadowPartition)) {
|
||||
delete fShadowPartition;
|
||||
fShadowPartition = NULL;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// notify the disk systems
|
||||
// parent disk system
|
||||
status_t error;
|
||||
if (Parent()) {
|
||||
error = Parent()->DiskSystem()->ShadowPartitionChanged(
|
||||
Parent()->ShadowPartition(), fShadowPartition,
|
||||
B_PARTITION_SHADOW_CHILD);
|
||||
if (error != B_OK) {
|
||||
UnsetShadowPartition(true);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
// this partition's disk system
|
||||
if (fShadowPartition->DiskSystem()) {
|
||||
error = fShadowPartition->DiskSystem()->ShadowPartitionChanged(
|
||||
fShadowPartition, NULL, B_PARTITION_SHADOW);
|
||||
if (error != B_OK) {
|
||||
UnsetShadowPartition(true);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create shadows for children
|
||||
for (int32 i = 0; KPartition *child = ChildAt(i); i++) {
|
||||
status_t error = child->CreateShadowPartition();
|
||||
if (error == B_OK)
|
||||
error = fShadowPartition->AddChild(child->ShadowPartition(), i);
|
||||
|
||||
// cleanup on error
|
||||
if (error != B_OK) {
|
||||
for (int32 k = 0; k <= i; i++)
|
||||
for (int32 k = 0; k <= i; k++)
|
||||
ChildAt(k)->UnsetShadowPartition(true);
|
||||
UnsetShadowPartition(true);
|
||||
return error;
|
||||
|
@ -26,6 +26,10 @@ using namespace BPrivate::DiskDevice;
|
||||
// debugging
|
||||
#define ERROR(x)
|
||||
|
||||
|
||||
// TODO: Add user address checks and check return values of user_memcpy()!
|
||||
|
||||
|
||||
// ddm_strlcpy
|
||||
/*! \brief Wrapper around user_strlcpy() that returns a status_t
|
||||
indicating appropriate success or failure.
|
||||
@ -70,7 +74,7 @@ move_descendants_contents(KPartition *partition)
|
||||
KDiskSystem *diskSystem = partition->DiskSystem();
|
||||
if (diskSystem || partition->AlgorithmData()) {
|
||||
status_t error = diskSystem->ShadowPartitionChanged(partition,
|
||||
B_PARTITION_RESIZE);
|
||||
NULL, B_PARTITION_MOVE);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
@ -284,46 +288,58 @@ status_t
|
||||
_user_get_partitionable_spaces(partition_id partitionID, int32 changeCounter,
|
||||
partitionable_space_data *_buffer, int32 count, int32 *_actualCount)
|
||||
{
|
||||
if (!_buffer && count > 0)
|
||||
if (count > 0 && !_buffer)
|
||||
return B_BAD_VALUE;
|
||||
// copy in
|
||||
|
||||
if (count > 0 && !IS_USER_ADDRESS(_buffer)
|
||||
|| _actualCount && !IS_USER_ADDRESS(_actualCount)) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
// allocate buffer
|
||||
int32 bufferSize = count * sizeof(partitionable_space_data);
|
||||
partitionable_space_data *buffer = count > 0
|
||||
? reinterpret_cast<partitionable_space_data*>(malloc(bufferSize))
|
||||
: NULL;
|
||||
if (buffer)
|
||||
user_memcpy(buffer, _buffer, bufferSize);
|
||||
partitionable_space_data *buffer = NULL;
|
||||
MemoryDeleter bufferDeleter;
|
||||
if (count > 0) {
|
||||
buffer = (partitionable_space_data*)malloc(bufferSize);
|
||||
if (!buffer)
|
||||
return B_NO_MEMORY;
|
||||
bufferDeleter.SetTo(buffer);
|
||||
}
|
||||
|
||||
status_t error = B_OK;
|
||||
|
||||
// get the partition
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
KPartition *partition = manager->ReadLockPartition(partitionID);
|
||||
error = partition ? (status_t)B_OK : (status_t)B_ENTRY_NOT_FOUND;
|
||||
if (!error) {
|
||||
PartitionRegistrar registrar1(partition, true);
|
||||
PartitionRegistrar registrar2(partition->Device(), true);
|
||||
DeviceReadLocker locker(partition->Device(), true);
|
||||
error = check_shadow_partition(partition, changeCounter)
|
||||
? B_OK : B_BAD_VALUE;
|
||||
if (!error) {
|
||||
// get the disk system
|
||||
KDiskSystem *diskSystem = partition->DiskSystem();
|
||||
error = diskSystem ? (status_t)B_OK : (status_t)B_ENTRY_NOT_FOUND;
|
||||
if (!error) {
|
||||
// get the info
|
||||
int32 actualCount;
|
||||
error = diskSystem->GetPartitionableSpaces(partition, buffer,
|
||||
count, &actualCount);
|
||||
if (!error && _actualCount) {
|
||||
user_memcpy(_actualCount, &actualCount,
|
||||
sizeof(actualCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!partition)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
PartitionRegistrar registrar1(partition, true);
|
||||
PartitionRegistrar registrar2(partition->Device(), true);
|
||||
DeviceReadLocker locker(partition->Device(), true);
|
||||
|
||||
if (!check_shadow_partition(partition, changeCounter))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get the disk system
|
||||
KDiskSystem *diskSystem = partition->DiskSystem();
|
||||
if (!diskSystem)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// get the info
|
||||
int32 actualCount;
|
||||
error = diskSystem->GetPartitionableSpaces(partition, buffer, count,
|
||||
&actualCount);
|
||||
|
||||
// copy out
|
||||
if (!error && buffer)
|
||||
if (_actualCount)
|
||||
user_memcpy(_actualCount, &actualCount, sizeof(actualCount));
|
||||
// copy even on error
|
||||
|
||||
if (error == B_OK && buffer)
|
||||
user_memcpy(_buffer, buffer, bufferSize);
|
||||
free(buffer);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -376,7 +392,6 @@ _user_get_disk_system_info(disk_system_id id, user_disk_system_info *_info)
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
if (KDiskSystem *diskSystem = manager->FindDiskSystem(id)) {
|
||||
DiskSystemLoader _(diskSystem, true);
|
||||
user_disk_system_info info;
|
||||
diskSystem->GetInfo(&info);
|
||||
user_memcpy(_info, &info, sizeof(info));
|
||||
@ -399,7 +414,6 @@ _user_get_next_disk_system_info(int32 *_cookie, user_disk_system_info *_info)
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
if (KDiskSystem *diskSystem = manager->NextDiskSystem(&cookie)) {
|
||||
DiskSystemLoader _(diskSystem, true);
|
||||
user_disk_system_info info;
|
||||
diskSystem->GetInfo(&info);
|
||||
user_memcpy(_info, &info, sizeof(info));
|
||||
@ -424,7 +438,6 @@ _user_find_disk_system(const char *_name, user_disk_system_info *_info)
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
if (KDiskSystem *diskSystem = manager->FindDiskSystem(name)) {
|
||||
DiskSystemLoader _(diskSystem, true);
|
||||
user_disk_system_info info;
|
||||
diskSystem->GetInfo(&info);
|
||||
user_memcpy(_info, &info, sizeof(info));
|
||||
@ -1146,9 +1159,8 @@ _user_get_next_supported_partition_type(partition_id partitionID,
|
||||
char type[B_DISK_DEVICE_TYPE_LENGTH];
|
||||
error = diskSystem->GetNextSupportedType(partition, &cookie,
|
||||
type);
|
||||
if (!error) {
|
||||
if (!error)
|
||||
error = ddm_strlcpy(_type, type, B_DISK_DEVICE_TYPE_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1352,13 +1364,13 @@ _user_resize_partition(partition_id partitionID, int32 changeCounter,
|
||||
partition->Changed(B_PARTITION_CHANGED_SIZE);
|
||||
// implicit partitioning system changes
|
||||
error = partition->Parent()->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_RESIZE_CHILD);
|
||||
partition->Parent(), partition, B_PARTITION_RESIZE_CHILD);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// implicit content disk system changes
|
||||
if (partition->DiskSystem()) {
|
||||
error = partition->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_RESIZE);
|
||||
partition, NULL, B_PARTITION_RESIZE);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
@ -1393,7 +1405,7 @@ _user_move_partition(partition_id partitionID, int32 changeCounter,
|
||||
partition->Changed(B_PARTITION_CHANGED_OFFSET);
|
||||
// implicit partitioning system changes
|
||||
error = partition->Parent()->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_MOVE_CHILD);
|
||||
partition->Parent(), partition, B_PARTITION_MOVE_CHILD);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// implicit descendants' content disk system changes
|
||||
@ -1435,7 +1447,7 @@ _user_set_partition_name(partition_id partitionID, int32 changeCounter,
|
||||
partition->Changed(B_PARTITION_CHANGED_NAME);
|
||||
// implicit partitioning system changes
|
||||
return partition->Parent()->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_SET_NAME);
|
||||
partition->Parent(), partition, B_PARTITION_SET_NAME);
|
||||
}
|
||||
|
||||
|
||||
@ -1474,7 +1486,7 @@ _user_set_partition_content_name(partition_id partitionID, int32 changeCounter,
|
||||
partition->Changed(B_PARTITION_CHANGED_CONTENT_NAME);
|
||||
// implicit content disk system changes
|
||||
return partition->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_SET_CONTENT_NAME);
|
||||
partition, NULL, B_PARTITION_SET_CONTENT_NAME);
|
||||
}
|
||||
|
||||
|
||||
@ -1508,7 +1520,7 @@ _user_set_partition_type(partition_id partitionID, int32 changeCounter,
|
||||
partition->Changed(B_PARTITION_CHANGED_TYPE);
|
||||
// implicit partitioning system changes
|
||||
return partition->Parent()->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_SET_TYPE);
|
||||
partition->Parent(), partition, B_PARTITION_SET_TYPE);
|
||||
}
|
||||
|
||||
|
||||
@ -1545,7 +1557,7 @@ _user_set_partition_parameters(partition_id partitionID, int32 changeCounter,
|
||||
partition->Changed(B_PARTITION_CHANGED_PARAMETERS);
|
||||
// implicit partitioning system changes
|
||||
error = partition->Parent()->DiskSystem()
|
||||
->ShadowPartitionChanged(partition,
|
||||
->ShadowPartitionChanged(partition->Parent(), partition,
|
||||
B_PARTITION_SET_PARAMETERS);
|
||||
}
|
||||
}
|
||||
@ -1588,7 +1600,7 @@ _user_set_partition_content_parameters(partition_id partitionID,
|
||||
partition->Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS);
|
||||
// implicit content disk system changes
|
||||
error = partition->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_SET_CONTENT_PARAMETERS);
|
||||
partition, NULL, B_PARTITION_SET_CONTENT_PARAMETERS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1679,7 +1691,7 @@ _user_initialize_partition(partition_id partitionID, int32 changeCounter,
|
||||
|
||||
// implicit content disk system changes
|
||||
return partition->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_INITIALIZE);
|
||||
partition, NULL, B_PARTITION_INITIALIZE);
|
||||
}
|
||||
|
||||
|
||||
@ -1749,16 +1761,16 @@ _user_create_child_partition(partition_id partitionID, int32 changeCounter,
|
||||
}
|
||||
// set the parameters
|
||||
child->SetOffset(offset);
|
||||
child->SetSize(offset);
|
||||
child->SetSize(size);
|
||||
error = child->SetType(type);
|
||||
}
|
||||
if (!error) {
|
||||
error = partition->SetParameters(parameters);
|
||||
error = child->SetParameters(parameters);
|
||||
}
|
||||
if (!error) {
|
||||
// implicit partitioning system changes
|
||||
error = partition->DiskSystem()->ShadowPartitionChanged(
|
||||
partition, B_PARTITION_CREATE_CHILD);
|
||||
partition, child, B_PARTITION_CREATE_CHILD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user