Addition of write support to the disk device manager. Courtesy of Tomas

Kucera and Jan Matejek.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21719 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-07-27 12:12:35 +00:00
parent 7548b9ae20
commit 2dc6403ddc
31 changed files with 1254 additions and 65 deletions
+5 -3
View File
@@ -14,9 +14,11 @@
extern "C" {
#endif
// C API partition representation
// Fields marked [sys] are set by the system and are not to be changed by
// the disk system modules.
/** \brief C API partition representation
*
* Fields marked [sys] are set by the system and are not to be changed by
* the disk system modules.
*/
typedef struct partition_data {
partition_id id; // [sys]
off_t offset;
@@ -4,6 +4,7 @@
#define _K_DISK_DEVICE_JOB_H
#include "disk_device_manager.h"
#include <KPartitionVisitor.h>
struct user_disk_device_job_info;
@@ -12,19 +13,41 @@ namespace DiskDevice {
class KDiskDeviceJobQueue;
/**
* Represents some action executed on the disk device.
*
* -
*/
class KDiskDeviceJob {
public:
/**
* Creates a new job
*
* \param type actual type of the job (see DiskDeviceDefs.h for details)
* \param partitionID the partition/device on which the action should be executed
* \param scopeID partition/device which is the highest in the hierarchy (i.e. closest
* to the root) that can be affected by the action
* - every descendant of this partition is marked busy and all ancestors are marked descendant-
busy
*/
KDiskDeviceJob(uint32 type, partition_id partitionID,
partition_id scopeID = -1);
virtual ~KDiskDeviceJob();
/**
* Unique identification of the job
*/
disk_job_id ID() const;
void SetJobQueue(KDiskDeviceJobQueue *queue);
KDiskDeviceJobQueue *JobQueue() const;
/**
* Gets actual type of the action
*/
uint32 Type() const;
void SetStatus(uint32 status);
uint32 Status() const;
@@ -54,9 +77,25 @@ public:
// triggers a notification
float Progress() const;
status_t GetInfo(user_disk_device_job_info *info);
status_t GetProgressInfo(disk_device_job_progress_info *info);
/**
* Do the actual work of the job.
*
* - is supposed to be implemented in descendants
* - doesn't have any parameter - every operation needs different ones -> they're passed
* to the constructor
* - the implementations will
* - check the parameters given in constructor (e.g. if given partition exists...)
* - check whether the partition has needed disk system (its own or parent - depends
* on the operation)
* - using the disk system, validate the operation for given params
* - finally execute the action
*
* \return B_OK when everything went OK, some error otherwise
*/
virtual status_t Do() = 0;
private:
@@ -76,6 +115,29 @@ private:
float fProgress;
static disk_job_id fNextID;
private:
/**
* Visitor which checks if every descendant of given partition is busy or descendant-busy
*/
struct IsNotBusyVisitor : KPartitionVisitor {
virtual bool VisitPre(KPartition * partition);
};
IsNotBusyVisitor fNotBusyVisitor;
protected:
//some stuff useful for all descendants
/**
* Checks if there's any descendant which is not busy/descendant-busy.
*
* - the condition of busy descendant is common for many disk device operations ->
* many jobs can use this
*
* \param partition the root of checked subtree of the whole partition hieararchy
*/
bool isPartitionNotBusy( KPartition * partition );
};
} // namespace DiskDevice
@@ -13,6 +13,7 @@ namespace DiskDevice {
class KDiskDeviceJob;
class KPartition;
/// \brief Common ancestor for disk system add-on wrappers
class KDiskSystem {
public:
KDiskSystem(const char *name);
@@ -13,6 +13,7 @@ struct file_system_module_info;
namespace BPrivate {
namespace DiskDevice {
/// \brief Wrapper for the C interface of a filesystem add-on.
class KFileSystem : public KDiskSystem {
public:
KFileSystem(const char *name);
@@ -21,6 +21,7 @@ class KPath;
class KPhysicalPartition;
class KShadowPartition;
/// \brief Class representing a single partition.
class KPartition {
public:
KPartition(partition_id id = -1);
@@ -10,6 +10,11 @@ struct partition_module_info;
namespace BPrivate {
namespace DiskDevice {
/**
* \brief Wrapper for the C interface of a partitioning system add-on.
*
* See \ref ddm_modules.h for better description of the interface.
*/
class KPartitioningSystem : public KDiskSystem {
public:
KPartitioningSystem(const char *name);
@@ -19,7 +24,9 @@ public:
// Scanning
/// Try to identify a given partition
virtual float Identify(KPartition *partition, void **cookie);
/// Scan the partition
virtual status_t Scan(KPartition *partition, void *cookie);
virtual void FreeIdentifyCookie(KPartition *partition, void *cookie);
virtual void FreeCookie(KPartition *partition);
@@ -27,88 +34,132 @@ public:
// Querying
/// Check whether the add-on supports repairing this partition.
virtual bool SupportsRepairing(KPartition *partition, bool checkOnly,
bool *whileMounted);
/// Check whether the add-on supports resizing this partition.
virtual bool SupportsResizing(KPartition *partition, bool *whileMounted);
/// Check whether the add-on supports resizing children of this partition.
virtual bool SupportsResizingChild(KPartition *child);
/// Check whether the add-on supports moving this partition.
virtual bool SupportsMoving(KPartition *partition, bool *isNoOp);
/// Check whether the add-on supports moving children of this partition.
virtual bool SupportsMovingChild(KPartition *child);
/// Check whether the add-on supports setting name of this partition.
virtual bool SupportsSettingName(KPartition *partition);
/// Check whether the add-on supports setting name to content of this partition.
virtual bool SupportsSettingContentName(KPartition *partition,
bool *whileMounted);
/// Check whether the add-on supports setting type of this partition.
virtual bool SupportsSettingType(KPartition *partition);
/// Check whether the add-on supports setting parameters of this partition.
virtual bool SupportsSettingParameters(KPartition *partition);
/// Check whether the add-on supports setting parameters to content of this partition.
virtual bool SupportsSettingContentParameters(KPartition *partition,
bool *whileMounted);
/// Check whether the add-on supports initializing this partition.
virtual bool SupportsInitializing(KPartition *partition);
/// Check whether the add-on supports initializing a child of this partition.
virtual bool SupportsInitializingChild(KPartition *child,
const char *diskSystem);
/// Check whether the add-on supports creating children of this partition.
virtual bool SupportsCreatingChild(KPartition *partition);
/// Check whether the add-on supports deleting children of this partition.
virtual bool SupportsDeletingChild(KPartition *child);
/// Check whether the add-on is a subsystem for a given partition.
virtual bool IsSubSystemFor(KPartition *partition);
/// Validates parameters for resizing a partition
virtual bool ValidateResize(KPartition *partition, off_t *size);
/// Validates parameters for resizing a child partition
virtual bool ValidateResizeChild(KPartition *child, off_t *size);
/// Validates parameters for moving a partition
virtual bool ValidateMove(KPartition *partition, off_t *start);
/// Validates parameters for moving a child partition
virtual bool ValidateMoveChild(KPartition *child, off_t *start);
/// Validates parameters for setting name of a partition
virtual bool ValidateSetName(KPartition *partition, char *name);
/// Validates parameters for setting name to content of a partition
virtual bool ValidateSetContentName(KPartition *partition, char *name);
/// Validates parameters for setting type of a partition
virtual bool ValidateSetType(KPartition *partition, const char *type);
/// Validates parameters for setting parameters of a partition
virtual bool ValidateSetParameters(KPartition *partition,
const char *parameters);
/// Validates parameters for setting parameters to content of a partition
virtual bool ValidateSetContentParameters(KPartition *parameters,
const char *parameters);
/// Validates parameters for initializing a partition
virtual bool ValidateInitialize(KPartition *partition, char *name,
const char *parameters);
/// Validates parameters for creating child of a partition
virtual bool ValidateCreateChild(KPartition *partition, off_t *start,
off_t *size, const char *type,
const char *parameters, int32 *index);
/// Counts partitionable spaces on a partition
virtual int32 CountPartitionableSpaces(KPartition *partition);
/// Retrieves a list of partitionable spaces on a partition
virtual status_t GetPartitionableSpaces(KPartition *partition,
partitionable_space_data *buffer,
int32 count,
int32 *actualCount = NULL);
/// Iterates through supported partition types
virtual status_t GetNextSupportedType(KPartition *partition, int32 *cookie,
char *type);
/// Translates the "pretty" content type to an internal type
virtual status_t GetTypeForContentType(const char *contentType,
char *type);
// Shadow partition modification
/// Calls for additional modifications when shadow partition is changed
virtual status_t ShadowPartitionChanged(KPartition *partition,
uint32 operation);
// Writing
/// Repairs a partition
virtual status_t Repair(KPartition *partition, bool checkOnly,
KDiskDeviceJob *job);
/// Resizes a partition
virtual status_t Resize(KPartition *partition, off_t size,
KDiskDeviceJob *job);
/// Resizes child of a partition
virtual status_t ResizeChild(KPartition *child, off_t size,
KDiskDeviceJob *job);
/// Moves a partition
virtual status_t Move(KPartition *partition, off_t offset,
KDiskDeviceJob *job);
/// Moves child of a partition
virtual status_t MoveChild(KPartition *child, off_t offset,
KDiskDeviceJob *job);
/// Sets name to a partition
virtual status_t SetName(KPartition *partition, char *name,
KDiskDeviceJob *job);
/// Sets name to content of a partition
virtual status_t SetContentName(KPartition *partition, char *name,
KDiskDeviceJob *job);
/// Sets type of a partition
virtual status_t SetType(KPartition *partition, char *type,
KDiskDeviceJob *job);
/// Sets parameters of a partition
virtual status_t SetParameters(KPartition *partition,
const char *parameters,
KDiskDeviceJob *job);
/// Sets parameters to content of a partition
virtual status_t SetContentParameters(KPartition *partition,
const char *parameters,
KDiskDeviceJob *job);
/// Creates a child partition
virtual status_t CreateChild(KPartition *partition, off_t offset,
off_t size, const char *type,
const char *parameters, KDiskDeviceJob *job,
KPartition **child = NULL,
partition_id childID = -1);
/// Deletes a child partition
virtual status_t DeleteChild(KPartition *child, KDiskDeviceJob *job);
/// Initializes a partition with this partitioning system
virtual status_t Initialize(KPartition *partition, const char *name,
const char *parameters, KDiskDeviceJob *job);
@@ -12,6 +12,7 @@ class KDiskDevice;
class KDiskSystem;
class KShadowPartition;
/// \brief Class representing an existing partition.
class KPhysicalPartition : public KPartition {
public:
KPhysicalPartition(partition_id id = -1);
@@ -11,6 +11,9 @@ namespace DiskDevice {
class KPhysicalPartition;
/// \brief Class representing a shadow of an existing partition.
///
/// See \ref path_kernel_structures for more information.
class KShadowPartition : public KPartition, private KPartitionListener {
public:
KShadowPartition(KPhysicalPartition *physicalPartition);
@@ -42,7 +42,9 @@ KernelMergeObject kernel_disk_device_manager.o :
KRepairJob.cpp
KResizeJob.cpp
KScanPartitionJob.cpp
KSetNameJob.cpp
KSetParametersJob.cpp
KSetTypeJob.cpp
KUninitializeJob.cpp
# utilities
@@ -243,3 +243,17 @@ KDiskDeviceJob::_NextID()
// fNextID
disk_job_id KDiskDeviceJob::fNextID = 0;
// IsNotBusyVisitor
bool KDiskDeviceJob::IsNotBusyVisitor::VisitPre( KPartition * partition ) {
return !(partition->IsBusy() || partition->IsDescendantBusy());
}
bool KDiskDeviceJob::isPartitionNotBusy( KPartition * partition ) {
if( !partition ) {
return false;
}
return partition->VisitEachDescendant(&fNotBusyVisitor);
}
@@ -10,8 +10,18 @@
#include "KDiskDeviceJob.h"
#include "KDiskDeviceJobFactory.h"
#include "KCreateChildJob.h"
#include "KDefragmentJob.h"
#include "KDeleteChildJob.h"
#include "KInitializeJob.h"
#include "KMoveJob.h"
#include "KRepairJob.h"
#include "KResizeJob.h"
#include "KScanPartitionJob.h"
#include "KSetNameJob.h"
#include "KSetParametersJob.h"
#include "KSetTypeJob.h"
#include "KUninitializeJob.h"
using namespace std;
@@ -30,8 +40,7 @@ KDiskDeviceJobFactory::~KDiskDeviceJobFactory()
KDiskDeviceJob *
KDiskDeviceJobFactory::CreateDefragmentJob(partition_id partitionID)
{
// not implemented
return NULL;
return new(nothrow) KDefragmentJob(partitionID);
}
@@ -39,8 +48,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateRepairJob(partition_id partitionID,
bool checkOnly)
{
// not implemented
return NULL;
return new(nothrow) KRepairJob(partitionID, checkOnly);
}
@@ -56,8 +64,8 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateMoveJob(partition_id parentID, partition_id partitionID,
off_t offset, const partition_id *contentsToMove, int32 contentsToMoveCount)
{
// not implemented
return NULL;
// TODO: this is wierd, what in hell are contentsToMove etc?
return new(nothrow) KMoveJob(parentID, partitionID, offset);
}
@@ -65,8 +73,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateSetNameJob(partition_id parentID,
partition_id partitionID, const char *name)
{
// not implemented
return NULL;
return new(nothrow) KSetNameJob(parentID, partitionID, name, 0);
}
@@ -74,8 +81,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateSetContentNameJob(partition_id partitionID,
const char *name)
{
// not implemented
return NULL;
return new(nothrow) KSetNameJob(0, partitionID, 0, name);
}
@@ -83,8 +89,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateSetTypeJob(partition_id parentID,
partition_id partitionID, const char *type)
{
// not implemented
return NULL;
return new(nothrow) KSetTypeJob(parentID, partitionID, type);
}
@@ -92,8 +97,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateSetParametersJob(partition_id parentID,
partition_id partitionID, const char *parameters)
{
// not implemented
return NULL;
return new(nothrow) KSetParametersJob(parentID, partitionID, parameters, 0);
}
@@ -101,8 +105,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateSetContentParametersJob(partition_id partitionID,
const char *parameters)
{
// not implemented
return NULL;
return new(nothrow) KSetParametersJob(0, partitionID, 0, parameters);
}
@@ -110,8 +113,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateInitializeJob(partition_id partitionID,
disk_system_id diskSystemID, const char *name, const char *parameters)
{
// not implemented
return NULL;
return new(nothrow) KInitializeJob(partitionID, diskSystemID, name, parameters);
}
@@ -127,8 +129,7 @@ KDiskDeviceJobFactory::CreateCreateChildJob(partition_id partitionID,
partition_id childID, off_t offset, off_t size, const char *type,
const char *parameters)
{
// not implemented
return NULL;
return new(nothrow) KCreateChildJob(partitionID, childID, offset, size, type, parameters);
}
@@ -136,8 +137,7 @@ KDiskDeviceJob *
KDiskDeviceJobFactory::CreateDeleteChildJob(partition_id parentID,
partition_id partitionID)
{
// not implemented
return NULL;
return new(nothrow) KDeleteChildJob(parentID, partitionID);
}
@@ -1,4 +1,7 @@
// KPartitioningSystem.cpp
/** \file KPartitioningSystem.cpp
*
* \brief Implementation of \ref KPartitioningSystem class
*/
#include <fcntl.h>
#include <stdlib.h>
@@ -499,17 +502,17 @@ KPartitioningSystem::Resize(KPartition *partition, off_t size,
return B_ENTRY_NOT_FOUND;
// lock partition and open partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->ReadLockPartition(partition->ID());
KPartition *_partition = manager->WriteLockPartition(partition->ID());
if (!_partition)
return B_ERROR;
int fd = -1;
{
PartitionRegistrar registrar(_partition, true);
PartitionRegistrar deviceRegistrar(_partition->Device(), true);
DeviceReadLocker locker(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (partition != _partition)
return B_ERROR;
status_t result = partition->Open(O_RDONLY, &fd);
status_t result = partition->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
@@ -526,25 +529,24 @@ KPartitioningSystem::ResizeChild(KPartition *child, off_t size,
KDiskDeviceJob *job)
{
// check parameters
if (!child || !job || size < 0)
if (!child || !job || !child->Parent() || size < 0)
return B_BAD_VALUE;
if (!fModule->resize_child)
return B_ENTRY_NOT_FOUND;
// lock partition and open (parent) partition device
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *_partition = manager->ReadLockPartition(child->ID());
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);
DeviceReadLocker locker(_partition->Device(), true);
DeviceWriteLocker locker(_partition->Device(), true);
if (child != _partition)
return B_ERROR;
if (!child->Parent())
return B_BAD_VALUE;
status_t result = child->Parent()->Open(O_RDONLY, &fd);
status_t result = child->Parent()->Open(O_RDWR, &fd);
if (result != B_OK)
return result;
}
@@ -560,8 +562,32 @@ status_t
KPartitioningSystem::Move(KPartition *partition, off_t offset,
KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job)
return B_BAD_VALUE;
if (!fModule->move)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->move(fd, partition->ID(), offset, job->ID());
// cleanup and return
close(fd);
return result;
}
// MoveChild
@@ -569,8 +595,33 @@ status_t
KPartitioningSystem::MoveChild(KPartition *child, off_t offset,
KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!child || !job || !child->Parent())
return B_BAD_VALUE;
if (!fModule->move_child)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->move_child(fd, child->Parent()->ID(), child->ID(), offset, job->ID());
// cleanup and return
close(fd);
return result;
}
// SetName
@@ -578,8 +629,32 @@ status_t
KPartitioningSystem::SetName(KPartition *partition, char *name,
KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !name)
return B_BAD_VALUE;
if (!fModule->set_name)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->set_name(fd, partition->ID(), name, job->ID());
// cleanup and return
close(fd);
return result;
}
// SetContentName
@@ -587,8 +662,32 @@ status_t
KPartitioningSystem::SetContentName(KPartition *partition, char *name,
KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !name)
return B_BAD_VALUE;
if (!fModule->set_content_name)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->set_content_name(fd, partition->ID(), name, job->ID());
// cleanup and return
close(fd);
return result;
}
// SetType
@@ -596,8 +695,32 @@ status_t
KPartitioningSystem::SetType(KPartition *partition, char *type,
KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !type)
return B_BAD_VALUE;
if (!fModule->set_type)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->set_type(fd, partition->ID(), type, job->ID());
// cleanup and return
close(fd);
return result;
}
// SetParameters
@@ -605,8 +728,32 @@ status_t
KPartitioningSystem::SetParameters(KPartition *partition,
const char *parameters, KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !parameters)
return B_BAD_VALUE;
if (!fModule->set_parameters)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->set_parameters(fd, partition->ID(), parameters, job->ID());
// cleanup and return
close(fd);
return result;
}
// SetContentParameters
@@ -615,8 +762,32 @@ KPartitioningSystem::SetContentParameters(KPartition *partition,
const char *parameters,
KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !parameters)
return B_BAD_VALUE;
if (!fModule->set_content_parameters)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->set_content_parameters(fd, partition->ID(), parameters, job->ID());
// cleanup and return
close(fd);
return result;
}
// Initialize
@@ -624,8 +795,32 @@ status_t
KPartitioningSystem::Initialize(KPartition *partition, const char *name,
const char *parameters, KDiskDeviceJob *job)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !name /*|| !parameters*/)
return B_BAD_VALUE;
if (!fModule->initialize)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->initialize(fd, partition->ID(), name, parameters, job->ID());
// cleanup and return
close(fd);
return result;
}
// CreateChild
@@ -635,8 +830,37 @@ KPartitioningSystem::CreateChild(KPartition *partition, off_t offset,
const char *parameters, KDiskDeviceJob *job,
KPartition **child, partition_id childID)
{
// to be implemented
return B_ERROR;
// check parameters
if (!partition || !job || !type /*|| !parameters*/ || !child)
return B_BAD_VALUE;
if (!fModule->create_child)
return B_ENTRY_NOT_FOUND;
// 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;
}
// let the module do its job
status_t result = fModule->create_child(fd, partition->ID(), offset, size,
type, parameters, job->ID(), &childID);
// find and return the child
*child = manager->FindPartition(childID, false);
// cleanup and return
close(fd);
return result;
}
// DeleteChild
@@ -1,4 +1,7 @@
// ddm_userland_interface.cpp
/** \file ddm_userland_interface.cpp
*
* \brief Interface for userspace calls.
*/
#include <stdlib.h>
@@ -721,7 +724,7 @@ _user_supports_initializing_partition(partition_id partitionID,
int32 changeCounter,
const char *_diskSystemName)
{
if (_diskSystemName)
if (!_diskSystemName)
return false;
char diskSystemName[B_DISK_SYSTEM_NAME_LENGTH];
status_t error = ddm_strlcpy(diskSystemName, _diskSystemName, B_DISK_SYSTEM_NAME_LENGTH);
@@ -969,10 +972,10 @@ _user_validate_initialize_partition(partition_id partitionID,
error = validate_initialize_partition(partition, changeCounter,
diskSystemName, name, parameters);
}
if (!error)
error = ddm_strlcpy(_name, name, B_DISK_DEVICE_NAME_LENGTH);
if (!error)
error = ddm_strlcpy(name, _name, B_DISK_DEVICE_NAME_LENGTH);
free(parameters);
return error;
return error;
}
// _user_validate_create_child_partition
@@ -1548,6 +1551,7 @@ _user_initialize_partition(partition_id partitionID, int32 changeCounter,
}
if (!error) {
partition->Changed(B_PARTITION_CHANGED_CONTENT_PARAMETERS);
partition->Changed(B_PARTITION_CHANGED_INITIALIZATION);
// implicit content disk system changes
error = partition->DiskSystem()->ShadowPartitionChanged(
partition, B_PARTITION_INITIALIZE);
@@ -1,3 +1,114 @@
// KCreateChildJob.cpp
#include "KCreateChildJob.h"
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include <string.h>
#include "ddm_operation_validation.h"
KCreateChildJob::KCreateChildJob(partition_id partition, partition_id child, off_t offset,
off_t size, const char *type, const char *parameters)
: KDiskDeviceJob( B_DISK_DEVICE_JOB_CREATE, partition, partition ),
fChildID( child ), fOffset( offset ), fSize( size ),
fType ( !type ? NULL : strcpy ( new char[strlen(type)+1], type ) ),
fParameters( !parameters ? NULL : strcpy( new char[strlen(parameters)+1], parameters ) )
{
SetDescription( "creating child of the partition" );
}
KCreateChildJob::~KCreateChildJob() {}
/**
* Do the actual creation
*
* \note in time of calling the \c KDiskSystem function for creating child, the partition is NOT locked
*/
status_t KCreateChildJob::Do() {
KDiskDeviceManager * manager = KDiskDeviceManager::Default();
KPartition * partition = manager->WriteLockPartition( PartitionID() );
if( partition ) {
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true);
if (!partition->DiskSystem()) {
SetErrorMessage("Partition has no disk system!");
return B_BAD_VALUE;
}
// all descendants should be marked busy/descendant busy
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't create child of non-busy partition!");
return B_ERROR;
}
KPartition * childPartition = manager->WriteLockPartition( fChildID );
if( !childPartition ) {
//TODO
}
off_t newOffset = fOffset;
off_t newSize = fSize;
status_t validation_result = validate_create_child_partition (
partition, partition->ChangeCounter(),
&newOffset, &fSize, fType,
fParameters, NULL, false
);
if( validation_result != B_OK ) {
SetErrorMessage( "Validating of creating new child failed!" );
return validation_result;
}
if( newOffset != fOffset ) {
SetErrorMessage( "Requested offset is not valid." );
return B_ERROR;
}
if( newSize != fSize ) {
SetErrorMessage( "Requested size is not valid" );
}
KDiskSystem *diskSystem = partition->DiskSystem();
DiskSystemLoader loader(diskSystem);
KPartition * newChild = 0;
locker.Unlock();
status_t create_result = diskSystem->CreateChild(
partition, newOffset, newSize, fType,
fParameters, this, &newChild, fChildID );
if( create_result != B_OK ) {
SetErrorMessage( "Creating new partition child failed!" );
return create_result;
}
return B_OK;
}
else {
SetErrorMessage( "Couldn't find partition." );
return B_ENTRY_NOT_FOUND;
}
}
@@ -8,13 +8,32 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Create new child of given partition
*/
class KCreateChildJob : public KDiskDeviceJob {
public:
/**
* Creates the job.
*
* \param partition whose children should we create
* \param child new child ID
* \param offset where the child should start
* \param size size of the new child
* \param parameters additional parameters for the operation
*/
KCreateChildJob(partition_id partition, partition_id child, off_t offset,
off_t size, const char *parameters);
off_t size, const char *type, const char *parameters);
virtual ~KCreateChildJob();
virtual status_t Do();
private:
partition_id fChildID;
off_t fOffset, fSize;
char * fType;
char * fParameters;
};
} // namespace DiskDevice
@@ -1,3 +1,92 @@
// KDefragmentJob.cpp
#include "KDefragmentJob.h"
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include <string.h>
#include "ddm_operation_validation.h"
KDefragmentJob::KDefragmentJob(partition_id partition)
: KDiskDeviceJob( B_DISK_DEVICE_JOB_DEFRAGMENT, partition, partition )
{
SetDescription( "defragmenting partition" );
}
KDefragmentJob::~KDefragmentJob() {}
status_t KDefragmentJob::Do(){
KDiskDeviceManager * manager = KDiskDeviceManager::Default();
KPartition * partition = manager->WriteLockPartition( PartitionID() );
if( partition ) {
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true);
//some basic checks
if (!partition->DiskSystem()) {
SetErrorMessage("Partition has no disk system!");
return B_BAD_VALUE;
}
// all descendants should be marked busy/descendant busy
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't defragment non-busy partition!");
return B_ERROR;
}
bool whileMounted;
//OK, seems alright, let's validate the job
status_t validation_result = validate_defragment_partition(
partition, partition->ChangeCounter(),
&whileMounted, false);
if( validation_result != B_OK ) {
SetErrorMessage( "Validation of defragmenting partition failed.");
return validation_result;
}
if( !whileMounted && partition->IsMounted() ) {
SetErrorMessage( "This partition cannot be defragmented while mounted." );
return B_ERROR;
}
//everything OK, let's do the job!
KDiskSystem *diskSystem = partition->DiskSystem();
DiskSystemLoader loader(diskSystem);
locker.Unlock();
status_t defrag_result = diskSystem->Defragment( partition, this );
if( defrag_result != B_OK ) {
SetErrorMessage( "Defragmenting partition failed!" );
return defrag_result;
}
return B_OK;
} else {
SetErrorMessage( "Couldn't find partition!" );
return B_ENTRY_NOT_FOUND;
}
}
@@ -8,8 +8,17 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Defragments the device
*/
class KDefragmentJob : public KDiskDeviceJob {
public:
/**
* Creates the job
*
* \param partition which device should we defragment
*/
KDefragmentJob(partition_id partition);
virtual ~KDefragmentJob();
@@ -1,3 +1,80 @@
// KDeleteChildJob.cpp
#include "KDeleteChildJob.h"
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include <string.h>
#include "ddm_operation_validation.h"
KDeleteChildJob::KDeleteChildJob(partition_id parent, partition_id partition)
: KDiskDeviceJob( B_DISK_DEVICE_JOB_DELETE, partition, parent )
{
SetDescription( "deleting child of the partition" );
}
KDeleteChildJob::~KDeleteChildJob() {}
status_t KDeleteChildJob::Do(){
KDiskDeviceManager * manager = KDiskDeviceManager::Default();
KPartition * partition = manager->WriteLockPartition( PartitionID() );
if( partition ) {
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true);
if (!partition->ParentDiskSystem()) {
SetErrorMessage("Partition has no parent disk system!");
return B_BAD_VALUE;
}
// all descendants should be marked busy/descendant busy
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't delete child of non-busy partition!");
return B_ERROR;
}
status_t validation_result = validate_delete_child_partition(
partition, partition->ChangeCounter(),
false);
if( validation_result != B_OK ) {
SetErrorMessage( "Validation of deleting child failed!" );
return validation_result;
}
//everything OK, let's do the job!
KDiskSystem *parentDiskSystem = partition->ParentDiskSystem();
DiskSystemLoader loader(parentDiskSystem );
locker.Unlock();
status_t delete_result = parentDiskSystem->DeleteChild( partition, this );
if( delete_result != B_OK ) {
SetErrorMessage( "Deleting child failed!" );
return delete_result;
}
return B_OK;
} else {
SetErrorMessage( "Couldn't find partition!" );
return B_ENTRY_NOT_FOUND;
}
}
@@ -8,8 +8,17 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Deletes specific child of a partition/device
*/
class KDeleteChildJob : public KDiskDeviceJob {
public:
/**
* Creates the job
*
* \param parent device of the deleted partition
* \param partition partition supposed to be removed
*/
KDeleteChildJob(partition_id parent, partition_id partition);
virtual ~KDeleteChildJob();
@@ -1,3 +1,105 @@
// KInitializeJob.cpp
#include <stdio.h>
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include <string.h>
#include "ddm_operation_validation.h"
#include "KInitializeJob.h"
// debugging
//#define DBG(x)
#define DBG(x) x
#define OUT dprintf
KInitializeJob::KInitializeJob(partition_id partition, disk_system_id diskSystemID,
const char *name, const char *parameters)
: KDiskDeviceJob( B_DISK_DEVICE_JOB_INITIALIZE, partition, partition ),
fDiskSystemID( diskSystemID ),
fName( !name ? NULL : strcpy( new char[strlen(name)+1], name ) ),
fParameters( !parameters ? NULL : strcpy( new char[strlen(parameters)+1], parameters ) )
{
SetDescription( "initializing the partition with given disk system" );
}
KInitializeJob::~KInitializeJob() {
delete[] fParameters;
}
status_t KInitializeJob::Do() {
DBG(OUT("KInitializeJob::Do(%ld)\n", PartitionID()));
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *partition = manager->WriteLockPartition(PartitionID());
if (partition) {
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true);
// basic checks
// if (!partition->ParentDiskSystem()) {
// SetErrorMessage("Partition has no parent disk system!");
// return B_BAD_VALUE;
// }
// all descendants should be marked busy/descendant busy
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't initialize non-busy partition!");
return B_ERROR;
}
/* if( !fParameters ) {
//no parameters for the operation
SetErrorMessage( "No parameters for partition initialization." );
return B_ERROR;
}*/
//TODO shouldn't we load the disk system AFTER the validation?
KDiskSystem *diskSystemToInit = manager->LoadDiskSystem( fDiskSystemID );
if( ! diskSystemToInit ) {
SetErrorMessage( "Given DiskSystemID doesn't correspond to any known DiskSystem.");
return B_BAD_VALUE;
}
DiskSystemLoader loader2(diskSystemToInit);
status_t validation_result = validate_initialize_partition(
partition, partition->ChangeCounter(),
diskSystemToInit->Name(), fName,
fParameters, false );
if( validation_result != B_OK ) {
SetErrorMessage( "Validation of initializing partition failed!" );
return validation_result;
}
//everything seems OK -> let's do the job
locker.Unlock();
status_t init_result = diskSystemToInit->Initialize( partition, fName, fParameters, this );
if( init_result != B_OK ) {
SetErrorMessage( "Initialization of partition failed!" );
return init_result;
}
partition->SetDiskSystem(diskSystemToInit);
return B_OK;
} else {
SetErrorMessage( "Couldn't find partition." );
return B_ENTRY_NOT_FOUND;
}
}
@@ -8,13 +8,29 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Initializes the device with given disk system (i.e. partitioning or file system)
*/
class KInitializeJob : public KDiskDeviceJob {
public:
/**
* Creates the job.
*
* \param partition the partition to initialize
* \param diskSystemID which disk system the partition should be initialized with
* \param parameters additional parameters for the operation
*/
KInitializeJob(partition_id partition, disk_system_id diskSystemID,
const char *parameters);
const char *name, const char *parameters);
virtual ~KInitializeJob();
virtual status_t Do();
private:
disk_system_id fDiskSystemID;
char * fName;
char * fParameters;
};
} // namespace DiskDevice
@@ -1,3 +1,98 @@
// KMoveJob.cpp
#include "KMoveJob.h"
#include <stdio.h>
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include "ddm_operation_validation.h"
// debugging
//#define DBG(x)
#define DBG(x) x
#define OUT dprintf
KMoveJob::KMoveJob(partition_id parentID, partition_id partitionID, off_t offset)
: KDiskDeviceJob(B_DISK_DEVICE_JOB_MOVE, partitionID, parentID ),
fNewOffset(offset)
{
SetDescription( "moving partition" );
}
KMoveJob::~KMoveJob() {}
status_t KMoveJob::Do() {
DBG(OUT( "KMoveJob::Do(%ld)\n", PartitionID() ));
//get the partition
KDiskDeviceManager * manager = KDiskDeviceManager::Default();
KPartition *partition = manager->WriteLockPartition(PartitionID());
if (partition) {
//OK, we have the partition, do some checks
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true);
// basic checks
if (!partition->ParentDiskSystem()) {
SetErrorMessage("Partition has no parent disk system!");
return B_BAD_VALUE;
}
if(partition->Offset() == fNewOffset ) {
//we are already on the right place -> nothing to do...
return B_OK;
}
off_t new_offset = fNewOffset;
status_t validate_result = validate_move_partition(partition, partition->ChangeCounter(),
&new_offset, true, false ); //TODO posledni 2 parametry????
if( validate_result != B_OK ) {
SetErrorMessage( "Validation of the new partition offset failed." );
return validate_result;
}
if( new_offset != fNewOffset ) {
SetErrorMessage( "Requested partition offset not valid." );
return B_ERROR;
}
// all descendants should be marked busy/descendant busy
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't move non-busy partition!");
return B_ERROR;
}
//get all necessary objects
KDiskSystem *parentDiskSystem = partition->ParentDiskSystem();
KDiskSystem *childDiskSystem = partition->DiskSystem();
locker.Unlock();
status_t move_result = parentDiskSystem->Move( partition, fNewOffset, this );
if( move_result != B_OK ) {
SetErrorMessage( "Moving of partition failed." );
}
return move_result;
//do the move
} else {
SetErrorMessage("Couldn't find partition.");
return B_ENTRY_NOT_FOUND;
}
return B_ERROR;
}
@@ -3,17 +3,31 @@
#ifndef _K_DISK_DEVICE_MOVE_JOB_H
#define _K_DISK_DEVICE_MOVE_JOB_H
#include "KDiskDeviceJob.h"
#include "KDiskDeviceJob.h"
namespace BPrivate {
namespace DiskDevice {
/**
* Moves given child of a partition/device
*/
class KMoveJob : public KDiskDeviceJob {
public:
KMoveJob(partition_id parent, partition_id partition, off_t offset);
/**
* Creates the job.
*
* \param parentID the device whose child should be moved
* \param partitionID the child to move
* \param offset where to move
*/
KMoveJob(partition_id parentID, partition_id partitionID, off_t offset);
virtual ~KMoveJob();
virtual status_t Do();
private:
off_t fNewOffset;
};
} // namespace DiskDevice
@@ -1,3 +1,95 @@
// KRepairJob.cpp
#include "KRepairJob.h"
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include <string.h>
#include "ddm_operation_validation.h"
KRepairJob::KRepairJob(partition_id partition, bool checkOnly)
: KDiskDeviceJob( B_DISK_DEVICE_JOB_REPAIR, partition, partition ),
fCheckOnly( checkOnly )
{
SetDescription( "repairing partition" );
}
KRepairJob::~KRepairJob() {}
status_t KRepairJob::Do(){
KDiskDeviceManager * manager = KDiskDeviceManager::Default();
KPartition * partition = manager->WriteLockPartition( PartitionID() );
if( partition ) {
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
DeviceWriteLocker locker(partition->Device(), true);
//basic checks
if( !partition->DiskSystem() ) {
SetErrorMessage( "Partition has no disk system." );
return B_BAD_VALUE;
}
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't repair non-busy partition!");
return B_ERROR;
}
bool whileMounted;
status_t validation_result = validate_repair_partition(
partition, partition->ChangeCounter(),
fCheckOnly, &whileMounted,
false);
if( validation_result != B_OK ) {
SetErrorMessage( "Validation repairing partition failed!" );
return validation_result;
}
//everything OK, let's do the job
KDiskSystem * diskSystem = partition->DiskSystem();
DiskSystemLoader loader(diskSystem);
locker.Unlock();
status_t repair_result = diskSystem->Repair( partition, fCheckOnly, this );
if( repair_result != B_OK ) {
if( fCheckOnly ) {
SetErrorMessage( "Checking for repairing partition failed!" );
} else {
SetErrorMessage( "Repairing partition failed!" );
}
return repair_result;
}
return B_OK;
}else {
SetErrorMessage( "Couldn't find partition!" );
return B_ENTRY_NOT_FOUND;
}
}
@@ -8,12 +8,25 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Repair partition (or check for repairs)
*/
class KRepairJob : public KDiskDeviceJob {
public:
KRepairJob(partition_id partition);
/**
* Creates the job.
*
* \param partition the partition which should be repared
* \param checkOnly when true, the partition is only checked, but no actual
* repairs are proceeded
*/
KRepairJob(partition_id partition, bool checkOnly);
virtual ~KRepairJob();
virtual status_t Do();
private:
bool fCheckOnly;
};
} // namespace DiskDevice
@@ -8,8 +8,18 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Resizes a partition.
*/
class KResizeJob : public KDiskDeviceJob {
public:
/**
* Creates the job.
*
* \param parentID the device whose child should be resized
* \param partitionID the partition which should be resized
* \param size new size for the partition
*/
KResizeJob(partition_id parentID, partition_id partitionID, off_t size);
virtual ~KResizeJob();
@@ -33,6 +33,12 @@ KScanPartitionJob::~KScanPartitionJob()
status_t
KScanPartitionJob::Do()
{
/*#ifdef _BOOT_MODE
OUT( "\nScanJob boot mode\n\n" );
#else
OUT( "\nScanJob NOT boot mode\n\n" );
#endif*/
// get the partition
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *partition = manager->WriteLockPartition(PartitionID());
@@ -10,14 +10,25 @@ namespace DiskDevice {
class KPartition;
/**
* Scans partition and tries to find the most suitable disk system for it
*/
class KScanPartitionJob : public KDiskDeviceJob {
public:
/**
* Creates the job.
*
* \param partitionID the partition to scan
*/
KScanPartitionJob(partition_id partitionID);
virtual ~KScanPartitionJob();
virtual status_t Do();
private:
/**
* Do the actual scan.
*/
status_t _ScanPartition(KPartition *partition);
};
@@ -1,3 +1,129 @@
// KSetParametersJob.cpp
#include <KernelExport.h>
#include <DiskDeviceDefs.h>
#include <KDiskDevice.h>
#include <KDiskDeviceManager.h>
#include <KDiskDeviceUtils.h>
#include <KDiskSystem.h>
#include <KPartition.h>
#include <KPartitionVisitor.h>
#include <string.h>
#include "KSetParametersJob.h"
#include "ddm_operation_validation.h"
KSetParametersJob::KSetParametersJob(partition_id parent, partition_id partition,
const char *parameters, const char *contentParameters)
: KDiskDeviceJob(B_DISK_DEVICE_JOB_SET_TYPE, partition, parent),
fParams( !parameters ? NULL : strcpy( new char[strlen(parameters)+1], parameters )),
fContentParams(
!contentParameters ? NULL :
strcpy( new char[strlen(contentParameters)+1], contentParameters))
{
SetDescription( "setting partition parameters&content parameters" );
}
KSetParametersJob::~KSetParametersJob(){}
status_t KSetParametersJob::Do(){
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
KPartition *partition = manager->WriteLockPartition(PartitionID());
if (partition) {
if( !fParams && !fContentParams ) {
SetErrorMessage( "No parameter to set." );
return B_BAD_VALUE;
}
PartitionRegistrar registrar(partition, true);
PartitionRegistrar deviceRegistrar(partition->Device(), true);
//TODO is lock necessary?
DeviceWriteLocker locker(partition->Device(), true);
// all descendants should be marked busy/descendant busy
if ( isPartitionNotBusy( partition ) ) {
SetErrorMessage("Can't set parameters for non-busy partition!");
return B_ERROR;
}
//TODO unlock?
if( fParams ) {
// basic checks
if (!partition->ParentDiskSystem()) {
SetErrorMessage("Partition has no parent disk system!");
return B_BAD_VALUE;
}
//TODO mayebe give copy of parameters?
//we have some parameters to set
status_t validation_result = validate_set_partition_parameters( partition, partition->ChangeCounter(), fParams, false );
KDiskSystem *parentDiskSystem = partition->ParentDiskSystem();
DiskSystemLoader loader(parentDiskSystem);
if( validation_result != B_OK ) {
SetErrorMessage( "Validation of setting partition parameters failed." );
return validation_result;
}
locker.Unlock();
status_t set_pars_result = parentDiskSystem->SetParameters( partition, fParams, this );
if( set_pars_result != B_OK ) {
SetErrorMessage( "Setting partition parameters failed." );
}
}
if( fContentParams ) {
// basic checks
if (!partition->DiskSystem()) {
SetErrorMessage("Partition has no disk system!");
return B_BAD_VALUE;
}
status_t validation_result = validate_set_partition_content_parameters (
partition, partition->ChangeCounter(), fContentParams, false );
if( validation_result != B_OK ) {
SetErrorMessage( "Validation of setting partition content parameters failed." );
return validation_result;
}
KDiskSystem *diskSystem = partition->DiskSystem();
DiskSystemLoader loader(diskSystem);
locker.Unlock();
status_t set_cont_pars_result = diskSystem->SetContentParameters(
partition, fContentParams, this );
if( set_cont_pars_result != B_OK ) {
SetErrorMessage( "Setting partition content parameters failed." );
}
}
return B_OK;
} else {
SetErrorMessage( "Couldn't find partition" );
return B_ENTRY_NOT_FOUND;
}
}
@@ -3,18 +3,36 @@
#ifndef _K_DISK_DEVICE_SET_PARAMETERS_JOB_H
#define _K_DISK_DEVICE_SET_PARAMETERS_JOB_H
#include "KDiskDeviceJob.h"
namespace BPrivate {
namespace DiskDevice {
#include "KDiskDeviceJob.h"
/**
* Sets the parameters for partition and/or for its content
*
* - can set both partition parameters and parameters for its content -
* but it's possible to create it with only one of these parameters
*/
class KSetParametersJob : public KDiskDeviceJob {
public:
/**
* Creates the job.
*
* \param partition the partition whose params (or content params) should be set
* \param parameters the new parameters for the partition
* \param contentParameters the new parameters for partition's content
*/
KSetParametersJob(partition_id parent, partition_id partition,
const char *parameters, const char *contentParameters);
virtual ~KSetParametersJob();
virtual status_t Do();
private:
char * fParams, * fContentParams;
};
} // namespace DiskDevice
@@ -8,8 +8,14 @@
namespace BPrivate {
namespace DiskDevice {
/**
* Uninitializes the partition/device
*/
class KUninitializeJob : public KDiskDeviceJob {
public:
/**
* Creates the job
*/
KUninitializeJob(partition_id partitionID);
virtual ~KUninitializeJob();