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:
Ingo Weinhold 2003-09-29 21:40:36 +00:00
parent 51e44e6ee4
commit 3acc9a051b
4 changed files with 532 additions and 407 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)