diff --git a/src/kernel/core/disk_device_manager/Jamfile b/src/kernel/core/disk_device_manager/Jamfile index cfd2e7795a..3d316e5c2a 100644 --- a/src/kernel/core/disk_device_manager/Jamfile +++ b/src/kernel/core/disk_device_manager/Jamfile @@ -14,6 +14,7 @@ SubDirCcFlags [ FDefines USER R5_MEMORY_LAYOUT ] ; SubDirC++Flags [ FDefines USER R5_MEMORY_LAYOUT ] ; SharedLibrary disk_device_manager : + ddm_operation_validation.cpp ddm_userland_interface.cpp disk_device_manager.cpp KDiskDevice.cpp diff --git a/src/kernel/core/disk_device_manager/ddm_operation_validation.cpp b/src/kernel/core/disk_device_manager/ddm_operation_validation.cpp new file mode 100644 index 0000000000..7f818fe148 --- /dev/null +++ b/src/kernel/core/disk_device_manager/ddm_operation_validation.cpp @@ -0,0 +1,449 @@ +// ddm_operation_validation.cpp + +#include +#include +#include +#include +#include + +#include "ddm_operation_validation.h" + +// static functions +namespace BPrivate { +namespace DiskDevice { + +static status_t check_busy_partition(const KPartition *partition, bool shadow); +static status_t check_partition(const KPartition *partition, + int32 changeCounter, bool shadow); + +} // namespace DiskDevice +} // namespace BPrivate + +// get_current_team +team_id +BPrivate::DiskDevice::get_current_team() +{ + // TODO: There must be a straighter way in kernelland. + thread_info info; + get_thread_info(find_thread(NULL), &info); + return info.team; +} + +// check_shadow_partition +bool +BPrivate::DiskDevice::check_shadow_partition(const KPartition *partition, + int32 changeCounter, + bool requireShadow) +{ + if (!partition || !partition->Device() + || partition->IsShadowPartition() != requireShadow + || changeCounter != partition->ChangeCounter()) { + return false; + } + if (!requireShadow) + return true; + return (partition->IsShadowPartition() + && partition->Device()->ShadowOwner() == get_current_team()); +} + +// check_busy_partition +static +status_t +BPrivate::DiskDevice::check_busy_partition(const KPartition *partition, + bool shadow) +{ + bool busy = (partition->IsBusy() || partition->IsDescendantBusy()); + if (shadow) { + if (busy) + return B_BUSY; + } else { + if (!busy) + return B_BAD_VALUE; + } + return B_OK; +} + +// check_partition +static +status_t +BPrivate::DiskDevice::check_partition(const KPartition *partition, + int32 changeCounter, bool shadow) +{ + if (!check_shadow_partition(partition, changeCounter, shadow)) + return B_BAD_VALUE; + bool busy = (partition->IsBusy() || partition->IsDescendantBusy()); + if (shadow) { + if (busy) + return B_BUSY; + } else { + if (!busy) + return B_BAD_VALUE; + } + return B_OK; +} + + +// get_unmovable_descendants +bool +BPrivate::DiskDevice::get_unmovable_descendants(KPartition *partition, + partition_id *&unmovable, size_t &unmovableSize, + partition_id *&needUnmounting, size_t &needUnmountingSize, + bool requireShadow) +{ + // check parameters + if (!partition || !unmovable || !needUnmounting || unmovableSize == 0 + || needUnmountingSize) { + return false; + } + // check partition + KDiskSystem *diskSystem = partition->DiskSystem(); + bool isNoOp = true; + bool supports = (diskSystem + && diskSystem->SupportsMoving(partition, &isNoOp)); + if (supports) { + unmovable[0] = partition->ID(); + unmovableSize--; + } + if (supports && !isNoOp && diskSystem->IsFileSystem()) { + needUnmounting[0] = partition->ID(); + needUnmountingSize--; + } + // check child partitions + for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) { + if (!get_unmovable_descendants(child, unmovable, unmovableSize, + needUnmounting, needUnmountingSize)) { + return false; + } + } + return true; +} + +// validate_move_descendants +status_t +BPrivate::DiskDevice::validate_move_descendants(KPartition *partition, + off_t moveBy, bool markMovable, bool requireShadow) +{ + if (!partition) + return B_BAD_VALUE; + // check partition + bool uninitialized = partition->IsUninitialized(); + KDiskSystem *diskSystem = partition->DiskSystem(); + bool movable = (uninitialized || diskSystem + || diskSystem->SupportsMoving(partition, NULL)); + if (markMovable) + partition->SetAlgorithmData(movable); + // moving partition is supported in principle, now check the new offset + if (!uninitialized) { + if (movable) { + off_t offset = partition->Offset() + moveBy; + off_t newOffset = offset; + if (!diskSystem->ValidateMove(partition, &newOffset) + || newOffset != offset) { + return B_ERROR; + } + } else + return B_ERROR; + // check children + for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) { + status_t error = validate_move_descendants(child, moveBy); + if (error != B_OK) + return error; + } + } + return B_OK; +} + +// validate_defragment_partition +status_t +BPrivate::DiskDevice::validate_defragment_partition(KPartition *partition, + int32 changeCounter, bool *whileMounted, bool requireShadow) +{ + status_t error = check_partition(partition, changeCounter, requireShadow); + if (error != B_OK) + return error; + // get the disk system and get the info + KDiskSystem *diskSystem = partition->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + if (diskSystem->SupportsDefragmenting(partition, whileMounted)) + return B_OK; + return B_ERROR; +} + +// validate_repair_partition +status_t +BPrivate::DiskDevice::validate_repair_partition(KPartition *partition, + int32 changeCounter, bool checkOnly, bool *whileMounted, + bool requireShadow) +{ + status_t error = check_partition(partition, changeCounter, requireShadow); + if (error != B_OK) + return error; + // get the disk system and get the info + KDiskSystem *diskSystem = partition->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + if (diskSystem->SupportsRepairing(partition, checkOnly, whileMounted)) + return B_OK; + return B_ERROR; +} + +// validate_resize_partition +status_t +BPrivate::DiskDevice::validate_resize_partition(KPartition *partition, + int32 changeCounter, off_t *size, off_t *contentSize, bool requireShadow) +{ + if (!partition || !size || !contentSize + || !check_shadow_partition(partition, changeCounter, requireShadow) + || !partition->Parent()) { + return B_BAD_VALUE; + } + status_t error = check_busy_partition(partition->Parent(), requireShadow); + if (error != B_OK) + return error; + // get the parent disk system and let it check the value + KDiskSystem *parentDiskSystem = partition->Parent()->DiskSystem(); + if (!parentDiskSystem) + return B_ENTRY_NOT_FOUND; + if (!parentDiskSystem->ValidateResizeChild(partition, size)) + return B_ERROR; + // if contents is uninitialized, then there's no need to check anything + // more + if (partition->IsUninitialized()) + return B_OK; + // get the child disk system and let it check the value + KDiskSystem *childDiskSystem = partition->DiskSystem(); + if (!childDiskSystem) + return B_ENTRY_NOT_FOUND; + *contentSize = *size; + // don't worry, if the content system desires to be smaller + if (!childDiskSystem->ValidateResize(partition, contentSize) + || *contentSize > *size) { + return B_ERROR; + } + return B_OK; +} + +// validate_move_partition +status_t +BPrivate::DiskDevice::validate_move_partition(KPartition *partition, + int32 changeCounter, off_t *newOffset, bool markMovable, + bool requireShadow) +{ + if (!partition || !newOffset + || !check_shadow_partition(partition, changeCounter, requireShadow) + || !partition->Parent()) { + return B_BAD_VALUE; + } + status_t error = check_busy_partition(partition->Parent(), requireShadow); + if (error != B_OK) + return error; + // get the parent disk system and let it check the value + KDiskSystem *parentDiskSystem = partition->Parent()->DiskSystem(); + if (!parentDiskSystem) + return B_ENTRY_NOT_FOUND; + if (!parentDiskSystem->ValidateMoveChild(partition, newOffset)) + return B_ERROR; + // let the concerned content disk systems check the value + return validate_move_descendants(partition, + partition->Offset() - *newOffset, markMovable); +} + +// validate_set_partition_name +status_t +BPrivate::DiskDevice::validate_set_partition_name(KPartition *partition, + int32 changeCounter, char *name, bool requireShadow) +{ + if (!partition || !name) + return B_BAD_VALUE; + // truncate name to maximal size + name[B_OS_NAME_LENGTH] = '\0'; + // check the partition + if (!check_shadow_partition(partition, changeCounter, requireShadow) + || !partition->Parent()) { + return B_BAD_VALUE; + } + status_t error = check_busy_partition(partition->Parent(), requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->ValidateSetName(partition, name)) + return B_OK; + return B_ERROR; +} + +// validate_set_partition_content_name +status_t +BPrivate::DiskDevice::validate_set_partition_content_name( + KPartition *partition, int32 changeCounter, char *name, bool requireShadow) +{ + if (!partition || !name) + return B_BAD_VALUE; + // truncate name to maximal size + name[B_OS_NAME_LENGTH] = '\0'; + // check the partition + status_t error = check_partition(partition, changeCounter, requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->ValidateSetContentName(partition, name)) + return B_OK; + return B_ERROR; +} + +// validate_set_partition_type +status_t +BPrivate::DiskDevice::validate_set_partition_type(KPartition *partition, + int32 changeCounter, const char *type, bool requireShadow) +{ + if (!partition || !type) + return B_BAD_VALUE; + // check the partition + if (!check_shadow_partition(partition, changeCounter, requireShadow) + || !partition->Parent()) { + return B_BAD_VALUE; + } + status_t error = check_busy_partition(partition->Parent(), requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->ValidateSetType(partition, type)) + return B_OK; + return B_ERROR; +} + +// validate_set_partition_parameters +status_t +BPrivate::DiskDevice::validate_set_partition_parameters(KPartition *partition, + int32 changeCounter, const char *parameters, bool requireShadow) +{ + if (!partition || !parameters) + return B_BAD_VALUE; + // check the partition + if (!check_shadow_partition(partition, changeCounter, requireShadow) + || !partition->Parent()) { + return B_BAD_VALUE; + } + status_t error = check_busy_partition(partition->Parent(), requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->ValidateSetParameters(partition, parameters)) + return B_OK; + return B_ERROR; +} + +// validate_set_partition_content_parameters +status_t +BPrivate::DiskDevice::validate_set_partition_content_parameters( + KPartition *partition, int32 changeCounter, const char *parameters, + bool requireShadow) +{ + // check the partition + status_t error = check_partition(partition, changeCounter, requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->ValidateSetContentParameters(partition, parameters)) + return B_OK; + return B_ERROR; +} + +// validate_initialize_partition +status_t +BPrivate::DiskDevice::validate_initialize_partition(KPartition *partition, + int32 changeCounter, const char *diskSystemName, char *name, + const char *parameters, bool requireShadow) +{ + if (!partition || !diskSystemName || !name) + return B_BAD_VALUE; + // truncate name to maximal size + name[B_OS_NAME_LENGTH] = '\0'; + // check the partition + status_t error = check_partition(partition, changeCounter, requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskDeviceManager *manager = KDiskDeviceManager::Default(); + KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemName); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + DiskSystemLoader loader(diskSystem, true); + // get the info + if (diskSystem->ValidateInitialize(partition, name, parameters)) + return B_OK; + return B_ERROR; +} + +// validate_create_child_partition +status_t +BPrivate::DiskDevice::validate_create_child_partition(KPartition *partition, + int32 changeCounter, off_t *offset, off_t *size, const char *type, + const char *parameters, int32 *index, bool requireShadow) +{ + if (!partition || !offset || !size || !type) + return B_BAD_VALUE; + // check the partition + status_t error = check_partition(partition, changeCounter, requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->ValidateCreateChild(partition, offset, size, type, + parameters, index)) { + return B_OK; + } + return B_ERROR; +} + +// validate_delete_child_partition +status_t +BPrivate::DiskDevice::validate_delete_child_partition(KPartition *partition, + int32 changeCounter, bool requireShadow) +{ + if (!partition) + return B_BAD_VALUE; + // check the partition + if (!check_shadow_partition(partition, changeCounter, requireShadow) + || !partition->Parent()) { + return B_BAD_VALUE; + } + status_t error = check_busy_partition(partition->Parent(), requireShadow); + if (error != B_OK) + return error; + // get the disk system + KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); + if (!diskSystem) + return B_ENTRY_NOT_FOUND; + // get the info + if (diskSystem->SupportsDeletingChild(partition)) + return B_OK; + return B_ERROR; +} + +//} // namespace DiskDevice +//} // namespace BPrivate + diff --git a/src/kernel/core/disk_device_manager/ddm_operation_validation.h b/src/kernel/core/disk_device_manager/ddm_operation_validation.h new file mode 100644 index 0000000000..99c9b2e9be --- /dev/null +++ b/src/kernel/core/disk_device_manager/ddm_operation_validation.h @@ -0,0 +1,74 @@ +// ddm_operation_validation.h + +#ifndef _DISK_DEVICE_MANAGER_OPERATION_VALIDATION_H +#define _DISK_DEVICE_MANAGER_OPERATION_VALIDATION_H + +#include + +#include + +namespace BPrivate { +namespace DiskDevice { + +class KPartition; + +team_id get_current_team(); +bool check_shadow_partition(const KPartition *partition, int32 changeCounter, + bool requireShadow = true); +bool get_unmovable_descendants(KPartition *partition, partition_id *&unmovable, + size_t &unmovableSize, + partition_id *&needUnmounting, + size_t &needUnmountingSize, + bool requireShadow = true); +status_t validate_move_descendants(KPartition *partition, off_t moveBy, + bool markMovable = false, + bool requireShadow = true); +status_t validate_defragment_partition(KPartition *partition, + int32 changeCounter, + bool *whileMounted = NULL, + bool requireShadow = true); +status_t validate_repair_partition(KPartition *partition, int32 changeCounter, + bool checkOnly, bool *whileMounted = NULL, + bool requireShadow = true); +status_t validate_resize_partition(KPartition *partition, int32 changeCounter, + off_t *size, off_t *contentSize, + bool requireShadow = true); +status_t validate_move_partition(KPartition *partition, int32 changeCounter, + off_t *newOffset, bool markMovable = false, + bool requireShadow = true); +status_t validate_set_partition_name(KPartition *partition, + int32 changeCounter, char *name, + bool requireShadow = true); +status_t validate_set_partition_content_name(KPartition *partition, + int32 changeCounter, char *name, + bool requireShadow = true); +status_t validate_set_partition_type(KPartition *partition, + int32 changeCounter, const char *type, + bool requireShadow = true); +status_t validate_set_partition_parameters(KPartition *partition, + int32 changeCounter, + const char *parameters, + bool requireShadow = true); +status_t validate_set_partition_content_parameters(KPartition *partition, + int32 changeCounter, + const char *parameters, + bool requireShadow = true); +status_t validate_initialize_partition(KPartition *partition, + int32 changeCounter, + const char *diskSystemName, char *name, + const char *parameters, + bool requireShadow = true); +status_t validate_create_child_partition(KPartition *partition, + int32 changeCounter, off_t *offset, + off_t *size, const char *type, + const char *parameters, + int32 *index = NULL, + bool requireShadow = true); +status_t validate_delete_child_partition(KPartition *partition, + int32 changeCounter, + bool requireShadow = true); + +} // namespace DiskDevice +} // namespace BPrivate + +#endif // _DISK_DEVICE_MANAGER_OPERATION_VALIDATION_H diff --git a/src/kernel/core/disk_device_manager/ddm_userland_interface.cpp b/src/kernel/core/disk_device_manager/ddm_userland_interface.cpp index 815c7c0c3d..d3ff80a7f8 100644 --- a/src/kernel/core/disk_device_manager/ddm_userland_interface.cpp +++ b/src/kernel/core/disk_device_manager/ddm_userland_interface.cpp @@ -14,205 +14,15 @@ #include #include +#include "ddm_operation_validation.h" #include "KDiskDeviceJobGenerator.h" #include "UserDataWriter.h" +using namespace BPrivate::DiskDevice; + // debugging #define ERROR(x) -// get_current_team -static -team_id -get_current_team() -{ - // TODO: There must be a straighter way in kernelland. - thread_info info; - get_thread_info(find_thread(NULL), &info); - return info.team; -} - -// check_shadow_partition -static -bool -check_shadow_partition(const KPartition *partition, int32 changeCounter) -{ - return (partition && partition->Device() && partition->IsShadowPartition() - && partition->Device()->ShadowOwner() == get_current_team() - && changeCounter == partition->ChangeCounter()); -} - -// get_unmovable_descendants -static -bool -get_unmovable_descendants(KPartition *partition, partition_id *&unmovable, - size_t &unmovableSize, partition_id *&needUnmounting, - size_t &needUnmountingSize) -{ - // check parameters - if (!partition || !unmovable || !needUnmounting || unmovableSize == 0 - || needUnmountingSize) { - return false; - } - // check partition - KDiskSystem *diskSystem = partition->DiskSystem(); - bool isNoOp = true; - bool supports = (diskSystem - && diskSystem->SupportsMoving(partition, &isNoOp)); - if (supports) { - unmovable[0] = partition->ID(); - unmovableSize--; - } - if (supports && !isNoOp && diskSystem->IsFileSystem()) { - needUnmounting[0] = partition->ID(); - needUnmountingSize--; - } - // check child partitions - for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) { - if (!get_unmovable_descendants(child, unmovable, unmovableSize, - needUnmounting, needUnmountingSize)) { - return false; - } - } - return true; -} - -// validate_move_descendants -static -status_t -validate_move_descendants(KPartition *partition, off_t moveBy, - bool markMovable = false) -{ - if (!partition) - return B_BAD_VALUE; - // check partition - bool uninitialized = partition->IsUninitialized(); - KDiskSystem *diskSystem = partition->DiskSystem(); - bool movable = (uninitialized || diskSystem - || diskSystem->SupportsMoving(partition, NULL)); - if (markMovable) - partition->SetAlgorithmData(movable); - // moving partition is supported in principle, now check the new offset - if (!uninitialized) { - if (movable) { - off_t offset = partition->Offset() + moveBy; - off_t newOffset = offset; - if (!diskSystem->ValidateMove(partition, &newOffset) - || newOffset != offset) { - return B_ERROR; - } - } else - return B_ERROR; - // check children - for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) { - status_t error = validate_move_descendants(child, moveBy); - if (error != B_OK) - return error; - } - } - return B_OK; -} - -// validate_defragment_partition -static -status_t -validate_defragment_partition(KPartition *partition, int32 changeCounter, - bool *whileMounted = NULL) -{ - if (!partition || !check_shadow_partition(partition, changeCounter)) - return B_BAD_VALUE; - if (partition->IsBusy() || partition->IsDescendantBusy()) - return B_BUSY; - // get the disk system and get the info - KDiskSystem *diskSystem = partition->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - if (diskSystem->SupportsDefragmenting(partition, whileMounted)) - return B_OK; - return B_ERROR; -} - -// validate_repair_partition -static -status_t -validate_repair_partition(KPartition *partition, int32 changeCounter, - bool checkOnly, bool *whileMounted = NULL) -{ - if (!partition || !check_shadow_partition(partition, changeCounter)) - return B_BAD_VALUE; - if (partition->IsBusy() || partition->IsDescendantBusy()) - return B_BUSY; - // get the disk system and get the info - KDiskSystem *diskSystem = partition->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - if (diskSystem->SupportsRepairing(partition, checkOnly, whileMounted)) - return B_OK; - return B_ERROR; -} - -// validate_resize_partition -static -status_t -validate_resize_partition(KPartition *partition, int32 changeCounter, - off_t *size) -{ - if (!partition || !size - || !check_shadow_partition(partition, changeCounter) - || !partition->Parent()) { - return B_BAD_VALUE; - } - if (partition->Parent()->IsBusy() - || partition->Parent()->IsDescendantBusy()) { - return B_BUSY; - } - // get the parent disk system and let it check the value - KDiskSystem *parentDiskSystem = partition->Parent()->DiskSystem(); - if (!parentDiskSystem) - return B_ENTRY_NOT_FOUND; - if (!parentDiskSystem->ValidateResizeChild(partition, size)) - return B_ERROR; - // if contents is uninitialized, then there's no need to check anything - // more - if (partition->IsUninitialized()) - return B_OK; - // get the child disk system and let it check the value - KDiskSystem *childDiskSystem = partition->DiskSystem(); - if (!childDiskSystem) - return B_ENTRY_NOT_FOUND; - off_t childSize = *size; - // don't worry, if the content system desires to be smaller - if (!childDiskSystem->ValidateResize(partition, &childSize) - || childSize > *size) { - return B_ERROR; - } - return B_OK; -} - -// validate_move_partition -status_t -validate_move_partition(KPartition *partition, int32 changeCounter, - off_t *newOffset, bool markMovable = false) -{ - if (!partition || !newOffset - || !check_shadow_partition(partition, changeCounter) - || !partition->Parent()) { - return B_BAD_VALUE; - } - if (partition->Parent()->IsBusy() - || partition->Parent()->IsDescendantBusy()) { - return B_BUSY; - } - // get the parent disk system and let it check the value - KDiskSystem *parentDiskSystem = partition->Parent()->DiskSystem(); - if (!parentDiskSystem) - return B_ENTRY_NOT_FOUND; - if (!parentDiskSystem->ValidateMoveChild(partition, newOffset)) - return B_ERROR; - // let the concerned content disk systems check the value - return validate_move_descendants(partition, - partition->Offset() - *newOffset, markMovable); -} - // move_descendants static void @@ -250,218 +60,6 @@ move_descendants_contents(KPartition *partition) return B_OK; } -// validate_set_partition_name -static -status_t -validate_set_partition_name(KPartition *partition, int32 changeCounter, - char *name) -{ - if (!partition || !name) - return B_BAD_VALUE; - // truncate name to maximal size - name[B_OS_NAME_LENGTH] = '\0'; - // check the partition - if (!check_shadow_partition(partition, changeCounter) - || !partition->Parent()) { - return B_BAD_VALUE; - } - if (partition->Parent()->IsBusy() - || partition->Parent()->IsDescendantBusy()) { - return B_BUSY; - } - // get the disk system - KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->ValidateSetName(partition, name)) - return B_OK; - return B_ERROR; -} - -// validate_set_partition_content_name -static -status_t -validate_set_partition_content_name(KPartition *partition, int32 changeCounter, - char *name) -{ - if (!partition || !name) - return B_BAD_VALUE; - // truncate name to maximal size - name[B_OS_NAME_LENGTH] = '\0'; - // check the partition - if (!check_shadow_partition(partition, changeCounter)) - return B_BAD_VALUE; - if (partition->IsBusy() || partition->IsDescendantBusy()) - return B_BUSY; - // get the disk system - KDiskSystem *diskSystem = partition->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->ValidateSetContentName(partition, name)) - return B_OK; - return B_ERROR; -} - -// validate_set_partition_type -static -status_t -validate_set_partition_type(KPartition *partition, int32 changeCounter, - const char *type) -{ - if (!partition || !type) - return B_BAD_VALUE; - // check the partition - if (!check_shadow_partition(partition, changeCounter) - || !partition->Parent()) { - return B_BAD_VALUE; - } - if (partition->Parent()->IsBusy() - || partition->Parent()->IsDescendantBusy()) { - return B_BUSY; - } - // get the disk system - KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->ValidateSetType(partition, type)) - return B_OK; - return B_ERROR; -} - -// validate_set_partition_parameters -static -status_t -validate_set_partition_parameters(KPartition *partition, int32 changeCounter, - const char *parameters) -{ - if (!partition || !parameters) - return B_BAD_VALUE; - // check the partition - if (!check_shadow_partition(partition, changeCounter) - || !partition->Parent()) { - return B_BAD_VALUE; - } - if (partition->Parent()->IsBusy() - || partition->Parent()->IsDescendantBusy()) { - return B_BUSY; - } - // get the disk system - KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->ValidateSetParameters(partition, parameters)) - return B_OK; - return B_ERROR; -} - -// validate_set_partition_content_parameters -static -status_t -validate_set_partition_content_parameters(KPartition *partition, - int32 changeCounter, - const char *parameters) -{ - if (!partition) - return B_BAD_VALUE; - // check the partition - if (!check_shadow_partition(partition, changeCounter)) - return B_BAD_VALUE; - if (partition->IsBusy() || partition->IsDescendantBusy()) - return B_BUSY; - // get the disk system - KDiskSystem *diskSystem = partition->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->ValidateSetContentParameters(partition, parameters)) - return B_OK; - return B_ERROR; -} - -// validate_initialize_partition -static -status_t -validate_initialize_partition(KPartition *partition, int32 changeCounter, - const char *diskSystemName, char *name, - const char *parameters) -{ - if (!partition || !diskSystemName || !name) - return B_BAD_VALUE; - // truncate name to maximal size - name[B_OS_NAME_LENGTH] = '\0'; - // check the partition - if (!check_shadow_partition(partition, changeCounter)) - return B_BAD_VALUE; - if (partition->IsBusy() || partition->IsDescendantBusy()) - return B_BUSY; - // get the disk system - KDiskDeviceManager *manager = KDiskDeviceManager::Default(); - KDiskSystem *diskSystem = manager->LoadDiskSystem(diskSystemName); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - DiskSystemLoader loader(diskSystem, true); - // get the info - if (diskSystem->ValidateInitialize(partition, name, parameters)) - return B_OK; - return B_ERROR; -} - -// validate_create_child_partition -static -status_t -validate_create_child_partition(KPartition *partition, int32 changeCounter, - off_t *offset, off_t *size, const char *type, - const char *parameters, int32 *index = NULL) -{ - if (!partition || !offset || !size || !type) - return B_BAD_VALUE; - // check the partition - if (!check_shadow_partition(partition, changeCounter)) - return B_BAD_VALUE; - if (partition->IsBusy() || partition->IsDescendantBusy()) - return B_BUSY; - // get the disk system - KDiskSystem *diskSystem = partition->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->ValidateCreateChild(partition, offset, size, type, - parameters, index)) { - return B_OK; - } - return B_ERROR; -} - -// validate_delete_child_partition -static -status_t -validate_delete_child_partition(KPartition *partition, int32 changeCounter) -{ - if (!partition) - return B_BAD_VALUE; - // check the partition - if (!check_shadow_partition(partition, changeCounter) - || !partition->Parent()) { - return B_BAD_VALUE; - } - if (partition->Parent()->IsBusy() - || partition->Parent()->IsDescendantBusy()) { - return B_BUSY; - } - // get the disk system - KDiskSystem *diskSystem = partition->Parent()->DiskSystem(); - if (!diskSystem) - return B_ENTRY_NOT_FOUND; - // get the info - if (diskSystem->SupportsDeletingChild(partition)) - return B_OK; - return B_ERROR; -} - // _kern_get_next_disk_device_id partition_id _kern_get_next_disk_device_id(int32 *_cookie, size_t *neededSize) @@ -1186,7 +784,9 @@ _kern_validate_resize_partition(partition_id partitionID, int32 changeCounter, PartitionRegistrar registrar1(partition, true); PartitionRegistrar registrar2(partition->Device(), true); DeviceReadLocker locker(partition->Device(), true); - bool result = validate_resize_partition(partition, changeCounter, &size); + off_t contentSize = 0; + bool result = validate_resize_partition(partition, changeCounter, &size, + &contentSize); if (result) *_size = size; return result; @@ -1506,8 +1106,9 @@ _kern_resize_partition(partition_id partitionID, int32 changeCounter, if (size == partition->Size()) return B_OK; off_t proposedSize = size; + off_t contentSize = 0; status_t error = validate_resize_partition(partition, changeCounter, - &proposedSize); + &proposedSize, &contentSize); if (error != B_OK) return error; if (proposedSize != size)