Files
haiku-beta6/src/system/kernel/disk_device_manager/KPartitioningSystem.cpp
T

899 lines
23 KiB
C++
Raw Normal View History

2007-07-27 16:32:47 +00:00
/*
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Ingo Weinhold <[email protected]>
* Lubos Kulic <[email protected]>
*/
/** \file KPartitioningSystem.cpp
*
* \brief Implementation of \ref KPartitioningSystem class
*/
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
2003-09-29 21:44:21 +00:00
#include <ddm_modules.h>
#include <KDiskDevice.h>
#include <KDiskDeviceJob.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KPartition.h>
#include <KPartitioningSystem.h>
2007-07-27 16:32:47 +00:00
// constructor
KPartitioningSystem::KPartitioningSystem(const char *name)
: KDiskSystem(name),
fModule(NULL)
{
}
// destructor
KPartitioningSystem::~KPartitioningSystem()
{
}
// Init
status_t
KPartitioningSystem::Init()
{
status_t error = KDiskSystem::Init();
if (error != B_OK)
return error;
error = Load();
if (error != B_OK)
return error;
error = SetPrettyName(fModule->pretty_name);
2003-07-18 18:41:21 +00:00
SetFlags(fModule->flags & ~(uint32)B_DISK_SYSTEM_IS_FILE_SYSTEM);
Unload();
return error;
}
// Identify
2007-07-27 16:32:47 +00:00
//! Try to identify a given partition
float
KPartitioningSystem::Identify(KPartition *partition, void **cookie)
{
if (!partition || !cookie || !fModule || !fModule->identify_partition)
return -1;
int fd = -1;
if (partition->Open(O_RDONLY, &fd) != B_OK)
return -1;
float result = fModule->identify_partition(fd, partition->PartitionData(),
2007-07-27 16:32:47 +00:00
cookie);
close(fd);
return result;
}
// Scan
2007-07-27 16:32:47 +00:00
//! Scan the partition
status_t
KPartitioningSystem::Scan(KPartition *partition, void *cookie)
{
if (!partition || !fModule || !fModule->scan_partition)
return B_ERROR;
int fd = -1;
status_t result = partition->Open(O_RDONLY, &fd);
if (result != B_OK)
return result;
result = fModule->scan_partition(fd, partition->PartitionData(), cookie);
close(fd);
return result;
}
// FreeIdentifyCookie
void
KPartitioningSystem::FreeIdentifyCookie(KPartition *partition, void *cookie)
{
if (!partition || !fModule || !fModule->free_identify_partition_cookie)
return;
fModule->free_identify_partition_cookie(partition->PartitionData(),
2007-07-27 16:32:47 +00:00
cookie);
}
// FreeCookie
void
KPartitioningSystem::FreeCookie(KPartition *partition)
{
if (!partition || !fModule || !fModule->free_partition_cookie
|| partition->ParentDiskSystem() != this) {
return;
}
fModule->free_partition_cookie(partition->PartitionData());
partition->SetCookie(NULL);
}
// FreeContentCookie
void
KPartitioningSystem::FreeContentCookie(KPartition *partition)
{
if (!partition || !fModule || !fModule->free_partition_content_cookie
|| partition->DiskSystem() != this) {
return;
}
fModule->free_partition_content_cookie(partition->PartitionData());
partition->SetContentCookie(NULL);
}
// GetSupportedOperations
uint32
KPartitioningSystem::GetSupportedOperations(KPartition* partition, uint32 mask)
{
ASSERT(partition != NULL);
// Note, that for initialization, the partition's disk system does not
// need to be this disk system.
if (!fModule)
return 0;
2003-06-22 23:03:17 +00:00
if (!fModule->get_supported_operations)
return (Flags() & mask);
return fModule->get_supported_operations(partition->PartitionData(), mask)
& mask;
}
// GetSupportedChildOperations
uint32
KPartitioningSystem::GetSupportedChildOperations(KPartition* child, uint32 mask)
2003-06-22 23:03:17 +00:00
{
ASSERT(child != NULL);
ASSERT(child->Parent() != NULL);
ASSERT(child->Parent()->DiskSystem() == this);
if (!fModule)
return 0;
if (!fModule->get_supported_child_operations)
return (Flags() & mask);
return fModule->get_supported_child_operations(
child->Parent()->PartitionData(), child->PartitionData(), mask)
& mask;
}
// SupportsInitializingChild
2007-08-12 23:54:15 +00:00
/*! Check whether the child partition managed by this partitioning system can
be initialized with the given disk system.
*/
bool
KPartitioningSystem::SupportsInitializingChild(KPartition *child,
2007-07-27 16:32:47 +00:00
const char *diskSystem)
{
if (!child || child->ParentDiskSystem() != this || !diskSystem
|| !fModule)
return false;
// If the hook is not implemented, the parent disk system doesn't want a
// veto.
if (!fModule->supports_initializing_child)
return true;
return fModule->supports_initializing_child(child->PartitionData(),
diskSystem);
}
// IsSubSystemFor
2007-07-27 16:32:47 +00:00
//! Check whether the add-on is a subsystem for a given partition.
bool
KPartitioningSystem::IsSubSystemFor(KPartition *partition)
{
return (partition && fModule && fModule->is_sub_system_for
2007-07-27 16:32:47 +00:00
&& fModule->is_sub_system_for(partition->PartitionData()));
}
// ValidateResize
2007-07-27 16:32:47 +00:00
//! Validates parameters for resizing a partition
bool
KPartitioningSystem::ValidateResize(KPartition *partition, off_t *size)
{
return (partition && size && partition->DiskSystem() == this && fModule
2007-07-27 16:32:47 +00:00
&& fModule->validate_resize
&& fModule->validate_resize(partition->PartitionData(), size));
}
2003-06-22 23:03:17 +00:00
// ValidateResizeChild
2007-07-27 16:32:47 +00:00
//! Validates parameters for resizing a child partition
bool
KPartitioningSystem::ValidateResizeChild(KPartition *child, off_t *size)
{
return (child && size && child->Parent()
2007-07-27 16:32:47 +00:00
&& child->ParentDiskSystem() == this && fModule
&& fModule->validate_resize_child
&& fModule->validate_resize_child(child->Parent()->PartitionData(),
child->PartitionData(), size));
}
2003-06-22 23:03:17 +00:00
// ValidateMove
2007-07-27 16:32:47 +00:00
//! Validates parameters for moving a partition
bool
2003-06-22 23:03:17 +00:00
KPartitioningSystem::ValidateMove(KPartition *partition, off_t *start)
{
return (partition && start && partition->DiskSystem() == this && fModule
2007-07-27 16:32:47 +00:00
&& fModule->validate_move
&& fModule->validate_move(partition->PartitionData(), start));
}
// ValidateMoveChild
2007-07-27 16:32:47 +00:00
//! Validates parameters for moving a child partition
bool
KPartitioningSystem::ValidateMoveChild(KPartition *child, off_t *start)
{
return (child && start && child->Parent()
2007-07-27 16:32:47 +00:00
&& child->ParentDiskSystem() == this && fModule
&& fModule->validate_move_child
&& fModule->validate_move_child(child->Parent()->PartitionData(),
child->PartitionData(), start));
}
// ValidateSetName
2007-07-27 16:32:47 +00:00
//! Validates parameters for setting name of a partition
bool
KPartitioningSystem::ValidateSetName(KPartition *partition, char *name)
{
return (partition && name && partition->Parent()
2007-07-27 16:32:47 +00:00
&& partition->ParentDiskSystem() == this && fModule
&& fModule->validate_set_name
&& fModule->validate_set_name(partition->PartitionData(), name));
}
// ValidateSetContentName
2007-07-27 16:32:47 +00:00
//! Validates parameters for setting name of the content of a partition
bool
KPartitioningSystem::ValidateSetContentName(KPartition *partition, char *name)
{
return (partition && name && partition->DiskSystem() == this
2007-07-27 16:32:47 +00:00
&& fModule && fModule->validate_set_content_name
&& fModule->validate_set_content_name(partition->PartitionData(),
name));
}
// ValidateSetType
2007-07-27 16:32:47 +00:00
//! Validates parameters for setting type of a partition
bool
KPartitioningSystem::ValidateSetType(KPartition *partition, const char *type)
{
return (partition && type && partition->ParentDiskSystem() == this
2007-07-27 16:32:47 +00:00
&& fModule && fModule->validate_set_type
&& fModule->validate_set_type(partition->PartitionData(), type));
}
// ValidateSetParameters
2007-07-27 16:32:47 +00:00
//! Validates parameters for setting parameters of a partition
bool
KPartitioningSystem::ValidateSetParameters(KPartition *partition,
2007-07-27 16:32:47 +00:00
const char *parameters)
{
return (partition && partition->ParentDiskSystem() == this
2007-07-27 16:32:47 +00:00
&& fModule && fModule->validate_set_parameters
&& fModule->validate_set_parameters(partition->PartitionData(),
parameters));
}
// ValidateSetContentParameters
2007-07-27 16:32:47 +00:00
//! Validates parameters for setting parameters of the content of a partition
bool
KPartitioningSystem::ValidateSetContentParameters(KPartition *partition,
2007-07-27 16:32:47 +00:00
const char *parameters)
{
return (partition && partition->DiskSystem() == this && fModule
&& fModule->validate_set_content_parameters
&& fModule->validate_set_content_parameters(
partition->PartitionData(), parameters));
}
// ValidateInitialize
2007-07-27 16:32:47 +00:00
//! Validates parameters for initializing a partition
bool
KPartitioningSystem::ValidateInitialize(KPartition *partition, char *name,
2007-07-27 16:32:47 +00:00
const char *parameters)
{
return (partition && name && fModule && fModule->validate_initialize
2007-07-27 16:32:47 +00:00
&& fModule->validate_initialize(partition->PartitionData(), name,
parameters));
}
// ValidateCreateChild
2007-07-27 16:32:47 +00:00
//! Validates parameters for creating child of a partition
bool
KPartitioningSystem::ValidateCreateChild(KPartition *partition, off_t *start,
2007-07-27 16:32:47 +00:00
off_t *size, const char *type, const char *parameters, int32 *index)
{
int32 _index = 0;
if (!index)
index = &_index;
return (partition && start && size && type
2007-07-27 16:32:47 +00:00
&& partition->DiskSystem() == this && fModule
&& fModule->validate_create_child
&& fModule->validate_create_child(partition->PartitionData(), start,
size, type, parameters, index));
}
// CountPartitionableSpaces
2007-07-27 16:32:47 +00:00
//! Counts partitionable spaces on a partition
int32
KPartitioningSystem::CountPartitionableSpaces(KPartition *partition)
{
if (!partition || partition->DiskSystem() != this || !fModule)
return 0;
if (!fModule->get_partitionable_spaces) {
// TODO: Fallback algorithm.
return 0;
}
int32 count = 0;
status_t error = fModule->get_partitionable_spaces(
partition->PartitionData(), NULL, 0, &count);
return (error == B_OK || error == B_BUFFER_OVERFLOW ? count : 0);
}
// GetPartitionableSpaces
2007-07-27 16:32:47 +00:00
//! Retrieves a list of partitionable spaces on a partition
status_t
KPartitioningSystem::GetPartitionableSpaces(KPartition *partition,
2007-07-27 16:32:47 +00:00
partitionable_space_data *buffer, int32 count, int32 *actualCount)
{
if (!partition || partition->DiskSystem() != this || count > 0 && !buffer
|| !actualCount || !fModule) {
return B_BAD_VALUE;
}
if (!fModule->get_partitionable_spaces) {
// TODO: Fallback algorithm.
return B_ENTRY_NOT_FOUND;
}
return fModule->get_partitionable_spaces(partition->PartitionData(),
2007-07-27 16:32:47 +00:00
buffer, count, actualCount);
}
// GetNextSupportedType
2007-07-27 16:32:47 +00:00
//! Iterates through supported partition types
status_t
KPartitioningSystem::GetNextSupportedType(KPartition *partition, int32 *cookie,
2007-07-27 16:32:47 +00:00
char *type)
{
if (!partition || partition->DiskSystem() != this || !cookie || !type
|| !fModule) {
return B_BAD_VALUE;
}
if (!fModule->get_next_supported_type)
return B_ENTRY_NOT_FOUND;
return fModule->get_next_supported_type(partition->PartitionData(), cookie,
type);
}
// GetTypeForContentType
2007-07-27 16:32:47 +00:00
//! Translates the "pretty" content type to an internal type
status_t
KPartitioningSystem::GetTypeForContentType(const char *contentType, char *type)
{
if (!contentType || !type || !fModule)
return B_BAD_VALUE;
if (!fModule->get_type_for_content_type)
return B_ENTRY_NOT_FOUND;
return fModule->get_type_for_content_type(contentType, type);
}
// ShadowPartitionChanged
2007-07-27 16:32:47 +00:00
//! Calls for additional modifications when shadow partition is changed
status_t
KPartitioningSystem::ShadowPartitionChanged(KPartition *partition,
2007-07-27 16:32:47 +00:00
uint32 operation)
{
if (!partition)
return B_BAD_VALUE;
if (!fModule)
return B_ERROR;
// If not implemented, we assume, that the partitioning system doesn't
// have to make any additional changes.
if (!fModule->shadow_changed)
return B_OK;
return fModule->shadow_changed(partition->PartitionData(), operation);
}
// Repair
2007-07-27 16:32:47 +00:00
//! Repairs a partition
status_t
KPartitioningSystem::Repair(KPartition *partition, bool checkOnly,
KDiskDeviceJob *job)
{
2003-06-22 23:03:17 +00:00
// to be implemented
return B_ERROR;
}
// Resize
2007-07-27 16:32:47 +00:00
//! Resizes a partition
status_t
KPartitioningSystem::Resize(KPartition *partition, off_t size,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
2003-09-29 21:44:21 +00:00
// check parameters
if (!partition || !job || size < 0)
return B_BAD_VALUE;
if (!fModule->resize)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
2003-09-29 21:44:21 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
2003-09-29 21:44:21 +00:00
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
2003-09-29 21:44:21 +00:00
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
2003-09-29 21:44:21 +00:00
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
2003-09-29 21:44:21 +00:00
// let the module do its job
status_t result = fModule->resize(fd, partition->ID(), size, job->ID());
2007-07-27 16:32:47 +00:00
2003-09-29 21:44:21 +00:00
// cleanup and return
close(fd);
return result;
}
// ResizeChild
2007-07-27 16:32:47 +00:00
//! Resizes child of a partition
status_t
KPartitioningSystem::ResizeChild(KPartition *child, off_t size,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
2003-09-29 21:44:21 +00:00
// check parameters
if (!child || !job || !child->Parent() || size < 0)
2003-09-29 21:44:21 +00:00
return B_BAD_VALUE;
if (!fModule->resize_child)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
2003-09-29 21:44:21 +00:00
// lock partition and open (parent) partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(child->ID());
KPartition *_parent = manager->WriteLockPartition(child->Parent()->ID());
2003-09-29 21:44:21 +00:00
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
2003-09-29 21:44:21 +00:00
if (child != _partition)
return B_ERROR;
status_t result = child->Parent()->Open(O_RDWR, &fd);
2003-09-29 21:44:21 +00:00
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
2003-09-29 21:44:21 +00:00
// let the module do its job
status_t result = fModule->resize_child(fd, child->ID(), size, job->ID());
2007-07-27 16:32:47 +00:00
2003-09-29 21:44:21 +00:00
// cleanup and return
close(fd);
return result;
}
// Move
2007-07-27 16:32:47 +00:00
//! Moves a partition
status_t
KPartitioningSystem::Move(KPartition *partition, off_t offset,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job)
return B_BAD_VALUE;
if (!fModule->move)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
status_t result = fModule->move(fd, partition->ID(), offset, job->ID());
2007-07-27 16:32:47 +00:00
// cleanup and return
close(fd);
return result;
}
// MoveChild
2007-07-27 16:32:47 +00:00
//! Moves child of a partition
status_t
KPartitioningSystem::MoveChild(KPartition *child, off_t offset,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
// check parameters
if (!child || !job || !child->Parent())
return B_BAD_VALUE;
if (!fModule->move_child)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open (parent) partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(child->ID());
KPartition *_parent = manager->WriteLockPartition(child->Parent()->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (child != _partition)
return B_ERROR;
status_t result = child->Parent()->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
2007-07-27 16:32:47 +00:00
status_t result = fModule->move_child(fd, child->Parent()->ID(),
child->ID(), offset, job->ID());
// cleanup and return
close(fd);
return result;
}
// SetName
2007-07-27 16:32:47 +00:00
//! Sets name of a partition
status_t
KPartitioningSystem::SetName(KPartition *partition, char *name,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job || !name)
return B_BAD_VALUE;
if (!fModule->set_name)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
status_t result = fModule->set_name(fd, partition->ID(), name, job->ID());
2007-07-27 16:32:47 +00:00
// cleanup and return
close(fd);
return result;
}
// SetContentName
2007-07-27 16:32:47 +00:00
//! Sets name of the content of a partition
status_t
KPartitioningSystem::SetContentName(KPartition *partition, char *name,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job || !name)
return B_BAD_VALUE;
if (!fModule->set_content_name)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
2007-07-27 16:32:47 +00:00
status_t result = fModule->set_content_name(fd, partition->ID(), name,
job->ID());
// cleanup and return
close(fd);
return result;
}
// SetType
2007-07-27 16:32:47 +00:00
//! Sets type of a partition
status_t
KPartitioningSystem::SetType(KPartition *partition, char *type,
2007-07-27 16:32:47 +00:00
KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job || !type)
return B_BAD_VALUE;
if (!fModule->set_type)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
status_t result = fModule->set_type(fd, partition->ID(), type, job->ID());
2007-07-27 16:32:47 +00:00
// cleanup and return
close(fd);
return result;
}
// SetParameters
2007-07-27 16:32:47 +00:00
//! Sets parameters of a partition
status_t
KPartitioningSystem::SetParameters(KPartition *partition,
2007-07-27 16:32:47 +00:00
const char *parameters, KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job || !parameters)
return B_BAD_VALUE;
if (!fModule->set_parameters)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
2007-07-27 16:32:47 +00:00
status_t result = fModule->set_parameters(fd, partition->ID(), parameters,
job->ID());
// cleanup and return
close(fd);
return result;
}
// SetContentParameters
2007-07-27 16:32:47 +00:00
//! Sets parameters of the content of a partition
status_t
KPartitioningSystem::SetContentParameters(KPartition *partition,
2007-07-27 16:32:47 +00:00
const char *parameters, KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job || !parameters)
return B_BAD_VALUE;
if (!fModule->set_content_parameters)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
2007-07-27 16:32:47 +00:00
status_t result = fModule->set_content_parameters(fd, partition->ID(),
parameters, job->ID());
// cleanup and return
close(fd);
return result;
}
// Initialize
2007-07-27 16:32:47 +00:00
//! Initializes a partition with this partitioning system
status_t
KPartitioningSystem::Initialize(KPartition *partition, const char *name,
2007-07-27 16:32:47 +00:00
const char *parameters, KDiskDeviceJob *job)
{
// check parameters
if (!partition || !job || !name /*|| !parameters*/)
return B_BAD_VALUE;
if (!fModule->initialize)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
// TODO: This looks overly complicated.
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
off_t partitionSize;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
partitionSize = partition->Size();
}
2007-07-27 16:32:47 +00:00
// let the module do its job
2007-07-27 16:32:47 +00:00
status_t result = fModule->initialize(fd, partition->ID(), name, parameters,
partitionSize, job->ID());
2007-07-27 16:32:47 +00:00
// cleanup and return
close(fd);
return result;
}
// CreateChild
2007-07-27 16:32:47 +00:00
//! Creates a child partition
status_t
KPartitioningSystem::CreateChild(KPartition *partition, off_t offset,
2007-07-27 16:32:47 +00:00
off_t size, const char *type, const char *parameters, KDiskDeviceJob *job,
KPartition **child, partition_id childID)
{
// check parameters
if (!partition || !job || !type /*|| !parameters*/ || !child)
return B_BAD_VALUE;
if (!fModule->create_child)
return B_ENTRY_NOT_FOUND;
2007-07-27 16:32:47 +00:00
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
2007-07-27 16:32:47 +00:00
// let the module do its job
status_t result = fModule->create_child(fd, partition->ID(), offset, size,
2007-07-27 16:32:47 +00:00
type, parameters, job->ID(), &childID);
// find and return the child
*child = manager->FindPartition(childID, false);
// cleanup and return
close(fd);
return result;
}
// DeleteChild
2007-07-27 16:32:47 +00:00
//! Deletes a child partition
status_t
KPartitioningSystem::DeleteChild(KPartition *child, KDiskDeviceJob *job)
{
2003-06-22 23:03:17 +00:00
// to be implemented
return B_ERROR;
}
// LoadModule
status_t
KPartitioningSystem::LoadModule()
{
if (fModule) // shouldn't happen
return B_OK;
return get_module(Name(), (module_info**)&fModule);
}
// UnloadModule
void
KPartitioningSystem::UnloadModule()
{
if (fModule) {
put_module(fModule->module.name);
fModule = NULL;
}
}