Moved the validation functions out of ddm_userland_interface.cpp into ddm_operation_validation.{cpp,h} for re-use.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4865 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
51e44e6ee4
commit
3acc9a051b
|
@ -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
|
||||
|
|
|
@ -0,0 +1,449 @@
|
|||
// ddm_operation_validation.cpp
|
||||
|
||||
#include <KDiskDevice.h>
|
||||
#include <KDiskDeviceManager.h>
|
||||
#include <KDiskDeviceUtils.h>
|
||||
#include <KDiskSystem.h>
|
||||
#include <KShadowPartition.h>
|
||||
|
||||
#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
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
// ddm_operation_validation.h
|
||||
|
||||
#ifndef _DISK_DEVICE_MANAGER_OPERATION_VALIDATION_H
|
||||
#define _DISK_DEVICE_MANAGER_OPERATION_VALIDATION_H
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include <disk_device_manager.h>
|
||||
|
||||
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
|
|
@ -14,205 +14,15 @@
|
|||
#include <KShadowPartition.h>
|
||||
#include <syscall_args.h>
|
||||
|
||||
#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)
|
||||
|
|
Loading…
Reference in New Issue