* Moved partition scanning back to KDiskDeviceManager. ATM only
synchronous scanning is supported.
* Removed the disk device job support from the disk device manager.
* K{Disk,File,Partitioning}System:
- Remove querying and validation methods.
- Commented out the modification methods until their fate is decided.
* Removed obsolete _user_get_partitionable_spaces().
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22799 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
* Lubos Kulic
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_JOB_H
|
||||
#define _K_DISK_DEVICE_JOB_H
|
||||
|
||||
#include "disk_device_manager.h"
|
||||
#include <KPartitionVisitor.h>
|
||||
|
||||
struct user_disk_device_job_info;
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KDiskDeviceJobQueue;
|
||||
|
||||
/**
|
||||
* Represents some action executed on the disk device.
|
||||
*/
|
||||
class KDiskDeviceJob {
|
||||
public:
|
||||
KDiskDeviceJob(uint32 type, partition_id partitionID,
|
||||
partition_id scopeID = -1);
|
||||
virtual ~KDiskDeviceJob();
|
||||
|
||||
disk_job_id ID() const;
|
||||
|
||||
void SetJobQueue(KDiskDeviceJobQueue *queue);
|
||||
KDiskDeviceJobQueue *JobQueue() const;
|
||||
|
||||
uint32 Type() const;
|
||||
|
||||
void SetStatus(uint32 status);
|
||||
uint32 Status() const;
|
||||
|
||||
status_t SetDescription(const char *description);
|
||||
const char *Description() const;
|
||||
|
||||
partition_id PartitionID() const;
|
||||
partition_id ScopeID() const;
|
||||
|
||||
status_t SetErrorMessage(const char *message);
|
||||
const char *ErrorMessage() const;
|
||||
|
||||
void SetTaskCount(int32 count);
|
||||
int32 TaskCount() const;
|
||||
|
||||
void SetCompletedTasks(int32 count);
|
||||
int32 CompletedTasks() const;
|
||||
|
||||
void SetInterruptProperties(uint32 properties);
|
||||
uint32 InterruptProperties() const;
|
||||
|
||||
virtual void GetTaskDescription(char *description);
|
||||
|
||||
void UpdateProgress(float progress);
|
||||
// may trigger a notification
|
||||
void UpdateExtraProgress(const char *info);
|
||||
// triggers a notification
|
||||
float Progress() const;
|
||||
|
||||
|
||||
status_t GetInfo(user_disk_device_job_info *info);
|
||||
status_t GetProgressInfo(disk_device_job_progress_info *info);
|
||||
|
||||
virtual status_t Do() = 0;
|
||||
|
||||
private:
|
||||
static disk_job_id _NextID();
|
||||
|
||||
disk_job_id fID;
|
||||
KDiskDeviceJobQueue *fJobQueue;
|
||||
uint32 fType;
|
||||
uint32 fStatus;
|
||||
partition_id fPartitionID;
|
||||
partition_id fScopeID;
|
||||
char *fDescription;
|
||||
char *fErrorMessage;
|
||||
int32 fTaskCount;
|
||||
int32 fCompletedTasks;
|
||||
uint32 fInterruptProperties;
|
||||
float fProgress;
|
||||
|
||||
static disk_job_id fNextID;
|
||||
|
||||
protected:
|
||||
// some stuff useful for all descendants
|
||||
|
||||
bool IsPartitionNotBusy(KPartition* partition);
|
||||
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KDiskDeviceJob;
|
||||
|
||||
#endif // _DISK_DEVICE_JOB_H
|
||||
@@ -1,59 +0,0 @@
|
||||
// KDiskDeviceJobFactory.h
|
||||
|
||||
#ifndef _K_DISK_DEVICE_JOB_FACTORY_H
|
||||
#define _K_DISK_DEVICE_JOB_FACTORY_H
|
||||
|
||||
#include "disk_device_manager.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KDiskDeviceJob;
|
||||
|
||||
class KDiskDeviceJobFactory {
|
||||
public:
|
||||
KDiskDeviceJobFactory();
|
||||
~KDiskDeviceJobFactory();
|
||||
|
||||
KDiskDeviceJob *CreateDefragmentJob(partition_id partitionID);
|
||||
KDiskDeviceJob *CreateRepairJob(partition_id partitionID, bool checkOnly);
|
||||
KDiskDeviceJob *CreateResizeJob(partition_id parentID,
|
||||
partition_id partitionID, off_t size);
|
||||
KDiskDeviceJob *CreateMoveJob(partition_id parentID,
|
||||
partition_id partitionID, off_t offset,
|
||||
const partition_id *contentsToMove,
|
||||
int32 contentsToMoveCount);
|
||||
KDiskDeviceJob *CreateSetNameJob(partition_id parentID,
|
||||
partition_id partitionID,
|
||||
const char *name);
|
||||
KDiskDeviceJob *CreateSetContentNameJob(partition_id partitionID,
|
||||
const char *name);
|
||||
KDiskDeviceJob *CreateSetTypeJob(partition_id parentID,
|
||||
partition_id partitionID,
|
||||
const char *type);
|
||||
KDiskDeviceJob *CreateSetParametersJob(partition_id parentID,
|
||||
partition_id partitionID,
|
||||
const char *parameters);
|
||||
KDiskDeviceJob *CreateSetContentParametersJob(partition_id partitionID,
|
||||
const char *parameters);
|
||||
KDiskDeviceJob *CreateInitializeJob(partition_id partitionID,
|
||||
disk_system_id diskSystemID,
|
||||
const char *name,
|
||||
const char *parameters);
|
||||
KDiskDeviceJob *CreateUninitializeJob(partition_id partitionID);
|
||||
KDiskDeviceJob *CreateCreateChildJob(partition_id partitionID,
|
||||
partition_id childID, off_t offset,
|
||||
off_t size, const char *type,
|
||||
const char *parameters);
|
||||
KDiskDeviceJob *CreateDeleteChildJob(partition_id parentID,
|
||||
partition_id partitionID);
|
||||
|
||||
KDiskDeviceJob *CreateScanPartitionJob(partition_id partitionID);
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KDiskDeviceJobFactory;
|
||||
|
||||
#endif // _K_DISK_DEVICE_JOB_FACTORY_H
|
||||
@@ -1,72 +0,0 @@
|
||||
// KDiskDeviceJobQueue.h
|
||||
|
||||
#ifndef _K_DISK_DEVICE_JOB_QUEUE_H
|
||||
#define _K_DISK_DEVICE_JOB_QUEUE_H
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "disk_device_manager.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KDiskDevice;
|
||||
class KDiskDeviceJob;
|
||||
|
||||
class KDiskDeviceJobQueue {
|
||||
public:
|
||||
KDiskDeviceJobQueue(KDiskDevice *device = NULL);
|
||||
~KDiskDeviceJobQueue();
|
||||
|
||||
status_t InitCheck() const;
|
||||
|
||||
void SetDevice(KDiskDevice *device);
|
||||
KDiskDevice *Device() const;
|
||||
|
||||
int32 ActiveJobIndex() const;
|
||||
KDiskDeviceJob *ActiveJob() const;
|
||||
|
||||
// list of scheduled jobs
|
||||
bool AddJob(KDiskDeviceJob *job);
|
||||
KDiskDeviceJob *RemoveJob(int32 index);
|
||||
bool RemoveJob(KDiskDeviceJob *job);
|
||||
// Adding/removing is only possible before the queues is added to the
|
||||
// manager.
|
||||
KDiskDeviceJob *JobAt(int32 index) const;
|
||||
int32 CountJobs() const;
|
||||
|
||||
status_t Execute();
|
||||
// Called by the manager, when the queue is added to it.
|
||||
// manager must be locked
|
||||
status_t Cancel(bool reverse);
|
||||
status_t Pause();
|
||||
status_t Continue();
|
||||
sem_id ReadyToPause();
|
||||
// called only by the queue's thread from within a module hook
|
||||
|
||||
bool IsExecuting() const;
|
||||
bool IsCanceled() const;
|
||||
bool ShallReverse() const;
|
||||
bool IsPaused() const;
|
||||
bool IsPauseRequested() const;
|
||||
|
||||
private:
|
||||
struct JobQueue;
|
||||
|
||||
int32 _ThreadLoop();
|
||||
static int32 _ThreadEntry(void *data);
|
||||
|
||||
KDiskDevice *fDevice;
|
||||
int32 fActiveJob;
|
||||
JobQueue *fJobs;
|
||||
uint32 fFlags;
|
||||
thread_id fThread;
|
||||
sem_id fSyncSemaphore;
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KDiskDeviceJobQueue;
|
||||
|
||||
#endif // _K_DISK_DEVICE_JOB_QUEUE_H
|
||||
@@ -16,9 +16,6 @@ namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KDiskDevice;
|
||||
class KDiskDeviceJob;
|
||||
class KDiskDeviceJobFactory;
|
||||
class KDiskDeviceJobQueue;
|
||||
class KDiskSystem;
|
||||
class KFileDiskDevice;
|
||||
class KPartition;
|
||||
@@ -66,10 +63,10 @@ public:
|
||||
// Both the device and the partition is also registered and must be
|
||||
// unregistered by the caller.
|
||||
|
||||
status_t ScanPartition(KPartition* partition, bool async);
|
||||
status_t ScanPartition(KPartition* partition);
|
||||
|
||||
partition_id CreateFileDevice(const char *filePath,
|
||||
bool *newlyCreated = NULL, bool async = true);
|
||||
partition_id CreateFileDevice(const char* filePath,
|
||||
bool* newlyCreated = NULL);
|
||||
status_t DeleteFileDevice(const char *filePath);
|
||||
status_t DeleteFileDevice(partition_id id);
|
||||
|
||||
@@ -81,29 +78,6 @@ public:
|
||||
bool PartitionRemoved(KPartition *partition); //
|
||||
bool DeletePartition(KPartition *partition); //
|
||||
|
||||
// Jobs
|
||||
|
||||
// manager must be locked
|
||||
KDiskDeviceJob *FindJob(disk_job_id id);
|
||||
int32 CountJobs();
|
||||
KDiskDeviceJob *NextJob(int32 *cookie);
|
||||
|
||||
// manager must be locked
|
||||
status_t AddJobQueue(KDiskDeviceJobQueue *jobQueue);
|
||||
// the device must be write locked
|
||||
status_t RemoveJobQueue(KDiskDeviceJobQueue *jobQueue);
|
||||
status_t DeleteJobQueue(KDiskDeviceJobQueue *jobQueue);
|
||||
// called when the execution is done
|
||||
int32 CountJobQueues();
|
||||
KDiskDeviceJobQueue *NextJobQueue(int32 *cookie);
|
||||
|
||||
KDiskDeviceJobFactory *JobFactory() const;
|
||||
|
||||
// manager must *not* be locked
|
||||
status_t UpdateBusyPartitions(KDiskDevice *device);
|
||||
status_t UpdateJobStatus(KDiskDeviceJob *job, uint32 status,
|
||||
bool updateBusyPartitions);
|
||||
|
||||
// Disk Systems
|
||||
|
||||
// manager must be locked
|
||||
@@ -137,20 +111,14 @@ private:
|
||||
bool _AddDevice(KDiskDevice *device);
|
||||
bool _RemoveDevice(KDiskDevice *device);
|
||||
|
||||
bool _RemoveJobQueue(KDiskDeviceJobQueue *jobQueue);
|
||||
|
||||
status_t _UpdateBusyPartitions(KDiskDevice *device);
|
||||
status_t _UpdateJobStatus(KDiskDeviceJob *job, uint32 status,
|
||||
bool updateBusyPartitions);
|
||||
|
||||
status_t _Scan(const char *path);
|
||||
status_t _ScanPartition(KPartition *partition, bool async);
|
||||
// the manager must be locked and the device write locked
|
||||
status_t _ScanPartition(KPartition *partition);
|
||||
// used by the other _ScanPartition() version only
|
||||
|
||||
struct DeviceMap;
|
||||
struct DiskSystemMap;
|
||||
struct JobMap;
|
||||
struct JobQueueVector;
|
||||
struct PartitionMap;
|
||||
struct PartitionSet;
|
||||
|
||||
@@ -159,9 +127,6 @@ private:
|
||||
PartitionMap *fPartitions;
|
||||
DiskSystemMap *fDiskSystems;
|
||||
PartitionSet *fObsoletePartitions;
|
||||
JobMap *fJobs;
|
||||
JobQueueVector *fJobQueues;
|
||||
KDiskDeviceJobFactory *fJobFactory;
|
||||
|
||||
static KDiskDeviceManager *sDefaultManager;
|
||||
};
|
||||
|
||||
@@ -15,7 +15,7 @@ struct user_disk_system_info;
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KDiskDeviceJob;
|
||||
//class KDiskDeviceJob;
|
||||
class KPartition;
|
||||
|
||||
//! \brief Common ancestor for disk system add-on wrappers
|
||||
@@ -51,60 +51,10 @@ public:
|
||||
virtual void FreeCookie(KPartition *partition);
|
||||
virtual void FreeContentCookie(KPartition *partition);
|
||||
|
||||
// Querying
|
||||
// Device must be read locked.
|
||||
|
||||
virtual uint32 GetSupportedOperations(KPartition* partition, uint32 mask);
|
||||
virtual uint32 GetSupportedChildOperations(KPartition* child, uint32 mask);
|
||||
|
||||
// for convenience
|
||||
bool SupportsOperations(KPartition* partition, uint32 operations)
|
||||
{ return (GetSupportedOperations(partition, operations) & operations)
|
||||
== operations; }
|
||||
bool SupportsChildOperations(KPartition* child, uint32 operations)
|
||||
{ return (GetSupportedChildOperations(child, operations) & operations)
|
||||
== operations; }
|
||||
|
||||
virtual bool SupportsInitializingChild(KPartition *child,
|
||||
const char *diskSystem);
|
||||
virtual bool IsSubSystemFor(KPartition *partition);
|
||||
|
||||
virtual bool ValidateResize(KPartition *partition, off_t *size);
|
||||
virtual bool ValidateResizeChild(KPartition *child, off_t *size);
|
||||
virtual bool ValidateMove(KPartition *partition, off_t *start);
|
||||
virtual bool ValidateMoveChild(KPartition *child, off_t *start);
|
||||
virtual bool ValidateSetName(KPartition *partition, char *name);
|
||||
virtual bool ValidateSetContentName(KPartition *partition, char *name);
|
||||
virtual bool ValidateSetType(KPartition *partition, const char *type);
|
||||
virtual bool ValidateSetParameters(KPartition *partition,
|
||||
const char *parameters);
|
||||
virtual bool ValidateSetContentParameters(KPartition *parameters,
|
||||
const char *parameters);
|
||||
virtual bool ValidateInitialize(KPartition *partition, char *name,
|
||||
const char *parameters);
|
||||
virtual bool ValidateCreateChild(KPartition *partition, off_t *start,
|
||||
off_t *size, const char *type,
|
||||
const char *parameters, int32 *index);
|
||||
virtual int32 CountPartitionableSpaces(KPartition *partition);
|
||||
virtual status_t GetPartitionableSpaces(KPartition *partition,
|
||||
partitionable_space_data *buffer,
|
||||
int32 count,
|
||||
int32 *actualCount = NULL);
|
||||
|
||||
virtual status_t GetNextSupportedType(KPartition *partition, int32 *cookie,
|
||||
char *type);
|
||||
virtual status_t GetTypeForContentType(const char *contentType,
|
||||
char *type);
|
||||
|
||||
// Shadow partition modification
|
||||
// Device must be write locked.
|
||||
|
||||
virtual status_t ShadowPartitionChanged(KPartition *partition,
|
||||
KPartition *child, uint32 operation);
|
||||
|
||||
// Writing
|
||||
// Device should not be locked.
|
||||
|
||||
#if 0
|
||||
virtual status_t Defragment(KPartition *partition, KDiskDeviceJob *job);
|
||||
virtual status_t Repair(KPartition *partition, bool checkOnly,
|
||||
KDiskDeviceJob *job);
|
||||
@@ -140,6 +90,7 @@ public:
|
||||
// since the device will not be locked, when they are called. The KPartition
|
||||
// is registered though, so that it is at least guaranteed that the object
|
||||
// won't go away.
|
||||
#endif // 0
|
||||
|
||||
protected:
|
||||
virtual status_t LoadModule();
|
||||
|
||||
@@ -33,25 +33,9 @@ public:
|
||||
virtual void FreeIdentifyCookie(KPartition *partition, void *cookie);
|
||||
virtual void FreeContentCookie(KPartition *partition);
|
||||
|
||||
// Querying
|
||||
|
||||
virtual uint32 GetSupportedOperations(KPartition* partition, uint32 mask);
|
||||
|
||||
virtual bool ValidateResize(KPartition *partition, off_t *size);
|
||||
virtual bool ValidateMove(KPartition *partition, off_t *start);
|
||||
virtual bool ValidateSetContentName(KPartition *partition, char *name);
|
||||
virtual bool ValidateSetContentParameters(KPartition *partition,
|
||||
const char *parameters);
|
||||
virtual bool ValidateInitialize(KPartition *partition, char *name,
|
||||
const char *parameters);
|
||||
|
||||
// Shadow partition modification
|
||||
|
||||
virtual status_t ShadowPartitionChanged(KPartition *partition,
|
||||
KPartition *child, uint32 operation);
|
||||
|
||||
// Writing
|
||||
|
||||
#if 0
|
||||
virtual status_t Defragment(KPartition *partition, KDiskDeviceJob *job);
|
||||
virtual status_t Repair(KPartition *partition, bool checkOnly,
|
||||
KDiskDeviceJob *job);
|
||||
@@ -66,6 +50,7 @@ public:
|
||||
KDiskDeviceJob *job);
|
||||
virtual status_t Initialize(KPartition *partition, const char *name,
|
||||
const char *parameters, KDiskDeviceJob *job);
|
||||
#endif // 0
|
||||
|
||||
protected:
|
||||
virtual status_t LoadModule();
|
||||
|
||||
@@ -35,49 +35,9 @@ public:
|
||||
virtual void FreeCookie(KPartition *partition);
|
||||
virtual void FreeContentCookie(KPartition *partition);
|
||||
|
||||
// Querying
|
||||
|
||||
virtual uint32 GetSupportedOperations(KPartition* partition, uint32 mask);
|
||||
virtual uint32 GetSupportedChildOperations(KPartition* child, uint32 mask);
|
||||
|
||||
virtual bool SupportsInitializingChild(KPartition *child,
|
||||
const char *diskSystem);
|
||||
virtual bool IsSubSystemFor(KPartition *partition);
|
||||
|
||||
virtual bool ValidateResize(KPartition *partition, off_t *size);
|
||||
virtual bool ValidateResizeChild(KPartition *child, off_t *size);
|
||||
virtual bool ValidateMove(KPartition *partition, off_t *start);
|
||||
virtual bool ValidateMoveChild(KPartition *child, off_t *start);
|
||||
virtual bool ValidateSetName(KPartition *partition, char *name);
|
||||
virtual bool ValidateSetContentName(KPartition *partition, char *name);
|
||||
virtual bool ValidateSetType(KPartition *partition, const char *type);
|
||||
virtual bool ValidateSetParameters(KPartition *partition,
|
||||
const char *parameters);
|
||||
virtual bool ValidateSetContentParameters(KPartition *parameters,
|
||||
const char *parameters);
|
||||
virtual bool ValidateInitialize(KPartition *partition, char *name,
|
||||
const char *parameters);
|
||||
virtual bool ValidateCreateChild(KPartition *partition, off_t *start,
|
||||
off_t *size, const char *type,
|
||||
const char *parameters, int32 *index);
|
||||
virtual int32 CountPartitionableSpaces(KPartition *partition);
|
||||
virtual status_t GetPartitionableSpaces(KPartition *partition,
|
||||
partitionable_space_data *buffer,
|
||||
int32 count,
|
||||
int32 *actualCount = NULL);
|
||||
|
||||
virtual status_t GetNextSupportedType(KPartition *partition, int32 *cookie,
|
||||
char *type);
|
||||
virtual status_t GetTypeForContentType(const char *contentType,
|
||||
char *type);
|
||||
|
||||
// Shadow partition modification
|
||||
|
||||
virtual status_t ShadowPartitionChanged(KPartition *partition,
|
||||
KPartition *child, uint32 operation);
|
||||
|
||||
// Writing
|
||||
|
||||
#if 0
|
||||
virtual status_t Repair(KPartition *partition, bool checkOnly,
|
||||
KDiskDeviceJob *job);
|
||||
virtual status_t Resize(KPartition *partition, off_t size,
|
||||
@@ -108,6 +68,7 @@ public:
|
||||
virtual status_t DeleteChild(KPartition *child, KDiskDeviceJob *job);
|
||||
virtual status_t Initialize(KPartition *partition, const char *name,
|
||||
const char *parameters, KDiskDeviceJob *job);
|
||||
#endif // 0
|
||||
|
||||
protected:
|
||||
virtual status_t LoadModule();
|
||||
|
||||
@@ -13,14 +13,9 @@ UsePrivateHeaders shared ;
|
||||
UsePrivateHeaders storage ;
|
||||
|
||||
KernelMergeObject kernel_disk_device_manager.o :
|
||||
ddm_operation_validation.cpp
|
||||
ddm_userland_interface.cpp
|
||||
disk_device_manager.cpp
|
||||
KDiskDevice.cpp
|
||||
KDiskDeviceJob.cpp
|
||||
KDiskDeviceJobFactory.cpp
|
||||
KDiskDeviceJobGenerator.cpp
|
||||
KDiskDeviceJobQueue.cpp
|
||||
KDiskDeviceManager.cpp
|
||||
KFileDiskDevice.cpp
|
||||
KDiskSystem.cpp
|
||||
@@ -33,20 +28,6 @@ KernelMergeObject kernel_disk_device_manager.o :
|
||||
KShadowPartition.cpp
|
||||
UserDataWriter.cpp
|
||||
|
||||
# jobs
|
||||
KCreateChildJob.cpp
|
||||
KDefragmentJob.cpp
|
||||
KDeleteChildJob.cpp
|
||||
KInitializeJob.cpp
|
||||
KMoveJob.cpp
|
||||
KRepairJob.cpp
|
||||
KResizeJob.cpp
|
||||
KScanPartitionJob.cpp
|
||||
KSetNameJob.cpp
|
||||
KSetParametersJob.cpp
|
||||
KSetTypeJob.cpp
|
||||
KUninitializeJob.cpp
|
||||
|
||||
# utilities
|
||||
Locker.cpp
|
||||
RWLocker.cpp
|
||||
|
||||
@@ -1,307 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "ddm_userland_interface.h"
|
||||
|
||||
#include <util/kernel_cpp.h>
|
||||
#include <KDiskDeviceJob.h>
|
||||
#include <KDiskDeviceUtils.h>
|
||||
|
||||
// debugging
|
||||
//#define DBG(x)
|
||||
#define DBG(x) x
|
||||
#define OUT dprintf
|
||||
|
||||
// constructor
|
||||
/**
|
||||
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::KDiskDeviceJob(uint32 type, partition_id partitionID,
|
||||
partition_id scopeID)
|
||||
: fID(_NextID()),
|
||||
fJobQueue(NULL),
|
||||
fType(type),
|
||||
fStatus(B_DISK_DEVICE_JOB_UNINITIALIZED),
|
||||
fPartitionID(partitionID),
|
||||
fScopeID(scopeID),
|
||||
fDescription(NULL),
|
||||
fErrorMessage(NULL),
|
||||
fTaskCount(1),
|
||||
fCompletedTasks(0),
|
||||
fInterruptProperties(0),
|
||||
fProgress(0)
|
||||
{
|
||||
if (fScopeID < 0)
|
||||
fScopeID = fPartitionID;
|
||||
}
|
||||
|
||||
// destructor
|
||||
KDiskDeviceJob::~KDiskDeviceJob()
|
||||
{
|
||||
if (fDescription)
|
||||
free(fDescription);
|
||||
}
|
||||
|
||||
// ID
|
||||
disk_job_id
|
||||
KDiskDeviceJob::ID() const
|
||||
{
|
||||
return fID;
|
||||
}
|
||||
|
||||
// SetJobQueue
|
||||
void
|
||||
KDiskDeviceJob::SetJobQueue(KDiskDeviceJobQueue *queue)
|
||||
{
|
||||
fJobQueue = queue;
|
||||
}
|
||||
|
||||
// JobQueue
|
||||
BPrivate::DiskDevice::KDiskDeviceJobQueue *
|
||||
KDiskDeviceJob::JobQueue() const
|
||||
{
|
||||
return fJobQueue;
|
||||
}
|
||||
|
||||
// Type
|
||||
uint32
|
||||
KDiskDeviceJob::Type() const
|
||||
{
|
||||
return fType;
|
||||
}
|
||||
|
||||
// SetStatus
|
||||
void
|
||||
KDiskDeviceJob::SetStatus(uint32 status)
|
||||
{
|
||||
fStatus = status;
|
||||
}
|
||||
|
||||
// Status
|
||||
uint32
|
||||
KDiskDeviceJob::Status() const
|
||||
{
|
||||
return fStatus;
|
||||
}
|
||||
|
||||
// SetDescription
|
||||
status_t
|
||||
KDiskDeviceJob::SetDescription(const char *description)
|
||||
{
|
||||
return set_string(fDescription, description);
|
||||
}
|
||||
|
||||
// Description
|
||||
const char *
|
||||
KDiskDeviceJob::Description() const
|
||||
{
|
||||
return fDescription;
|
||||
}
|
||||
|
||||
// PartitionID
|
||||
partition_id
|
||||
KDiskDeviceJob::PartitionID() const
|
||||
{
|
||||
return fPartitionID;
|
||||
}
|
||||
|
||||
// ScopeID
|
||||
partition_id
|
||||
KDiskDeviceJob::ScopeID() const
|
||||
{
|
||||
return fScopeID;
|
||||
}
|
||||
|
||||
// SetErrorMessage
|
||||
status_t
|
||||
KDiskDeviceJob::SetErrorMessage(const char *message)
|
||||
{
|
||||
return set_string(fErrorMessage, message);
|
||||
}
|
||||
|
||||
// ErrorMessage
|
||||
const char *
|
||||
KDiskDeviceJob::ErrorMessage() const
|
||||
{
|
||||
return fErrorMessage;
|
||||
}
|
||||
|
||||
// SetTaskCount
|
||||
void
|
||||
KDiskDeviceJob::SetTaskCount(int32 count)
|
||||
{
|
||||
fTaskCount = count;
|
||||
}
|
||||
|
||||
// TaskCount
|
||||
int32
|
||||
KDiskDeviceJob::TaskCount() const
|
||||
{
|
||||
return fTaskCount;
|
||||
}
|
||||
|
||||
// SetCompletedTasks
|
||||
void
|
||||
KDiskDeviceJob::SetCompletedTasks(int32 count)
|
||||
{
|
||||
fCompletedTasks = count;
|
||||
}
|
||||
|
||||
// CompletedTasks
|
||||
int32
|
||||
KDiskDeviceJob::CompletedTasks() const
|
||||
{
|
||||
return fCompletedTasks;
|
||||
}
|
||||
|
||||
// SetInterruptProperties
|
||||
void
|
||||
KDiskDeviceJob::SetInterruptProperties(uint32 properties)
|
||||
{
|
||||
fInterruptProperties = properties;
|
||||
}
|
||||
|
||||
// InterruptProperties
|
||||
uint32
|
||||
KDiskDeviceJob::InterruptProperties() const
|
||||
{
|
||||
return fInterruptProperties;
|
||||
}
|
||||
|
||||
// GetTaskDescription
|
||||
void
|
||||
KDiskDeviceJob::GetTaskDescription(char *description)
|
||||
{
|
||||
if (!description)
|
||||
return;
|
||||
if (fDescription)
|
||||
strcpy(description, fDescription);
|
||||
else
|
||||
description[0] = '\0';
|
||||
}
|
||||
|
||||
// UpdateProgress
|
||||
void
|
||||
KDiskDeviceJob::UpdateProgress(float progress)
|
||||
{
|
||||
if (fProgress == progress)
|
||||
return;
|
||||
fProgress = progress;
|
||||
// TODO: notification
|
||||
}
|
||||
|
||||
// UpdateExtraProgress
|
||||
void
|
||||
KDiskDeviceJob::UpdateExtraProgress(const char *info)
|
||||
{
|
||||
// TODO:...
|
||||
}
|
||||
|
||||
// Progress
|
||||
float
|
||||
KDiskDeviceJob::Progress() const
|
||||
{
|
||||
return fProgress;
|
||||
}
|
||||
|
||||
// GetInfo
|
||||
status_t
|
||||
KDiskDeviceJob::GetInfo(user_disk_device_job_info *info)
|
||||
{
|
||||
if (!info)
|
||||
return B_BAD_VALUE;
|
||||
info->id = ID();
|
||||
info->type = Type();
|
||||
info->partition = PartitionID();
|
||||
if (Description())
|
||||
strcpy(info->description, Description());
|
||||
else
|
||||
info->description[0] = '\0';
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// GetProgressInfo
|
||||
status_t
|
||||
KDiskDeviceJob::GetProgressInfo(disk_device_job_progress_info *info)
|
||||
{
|
||||
if (!info)
|
||||
return B_BAD_VALUE;
|
||||
info->status = Status();
|
||||
info->interrupt_properties = InterruptProperties();
|
||||
info->task_count = TaskCount();
|
||||
info->completed_tasks = CompletedTasks();
|
||||
info->current_task_progress = Progress();
|
||||
GetTaskDescription(info->current_task_description);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/** \fn status_t KDiskDevice::Do()
|
||||
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
|
||||
*/
|
||||
|
||||
// _NextID
|
||||
disk_job_id
|
||||
KDiskDeviceJob::_NextID()
|
||||
{
|
||||
return atomic_add(&fNextID, 1);
|
||||
}
|
||||
|
||||
// fNextID
|
||||
disk_job_id KDiskDeviceJob::fNextID = 0;
|
||||
|
||||
|
||||
/**
|
||||
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
|
||||
hierarchy
|
||||
*/
|
||||
bool
|
||||
KDiskDeviceJob::IsPartitionNotBusy(KPartition* partition)
|
||||
{
|
||||
if( !partition ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct IsNotBusyVisitor : KPartitionVisitor {
|
||||
virtual bool VisitPre(KPartition* partition)
|
||||
{
|
||||
return !(partition->IsBusy() || partition->IsDescendantBusy());
|
||||
}
|
||||
};
|
||||
IsNotBusyVisitor notBusyVisitor;
|
||||
|
||||
return partition->VisitEachDescendant(¬BusyVisitor);
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#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;
|
||||
|
||||
|
||||
KDiskDeviceJobFactory::KDiskDeviceJobFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJobFactory::~KDiskDeviceJobFactory()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateDefragmentJob(partition_id partitionID)
|
||||
{
|
||||
return new(nothrow) KDefragmentJob(partitionID);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateRepairJob(partition_id partitionID,
|
||||
bool checkOnly)
|
||||
{
|
||||
return new(nothrow) KRepairJob(partitionID, checkOnly);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateResizeJob(partition_id parentID,
|
||||
partition_id partitionID, off_t size)
|
||||
{
|
||||
return new(nothrow) KResizeJob(parentID, partitionID, size);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateMoveJob(partition_id parentID,
|
||||
partition_id partitionID, off_t offset, const partition_id *contentsToMove,
|
||||
int32 contentsToMoveCount)
|
||||
{
|
||||
// TODO: this is wierd, what in hell are contentsToMove etc?
|
||||
return new(nothrow) KMoveJob(parentID, partitionID, offset);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateSetNameJob(partition_id parentID,
|
||||
partition_id partitionID, const char *name)
|
||||
{
|
||||
return new(nothrow) KSetNameJob(parentID, partitionID, name, 0);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateSetContentNameJob(partition_id partitionID,
|
||||
const char *name)
|
||||
{
|
||||
return new(nothrow) KSetNameJob(0, partitionID, 0, name);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateSetTypeJob(partition_id parentID,
|
||||
partition_id partitionID, const char *type)
|
||||
{
|
||||
return new(nothrow) KSetTypeJob(parentID, partitionID, type);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateSetParametersJob(partition_id parentID,
|
||||
partition_id partitionID, const char *parameters)
|
||||
{
|
||||
return new(nothrow) KSetParametersJob(parentID, partitionID, parameters, 0);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateSetContentParametersJob(partition_id partitionID,
|
||||
const char *parameters)
|
||||
{
|
||||
return new(nothrow) KSetParametersJob(0, partitionID, 0, parameters);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateInitializeJob(partition_id partitionID,
|
||||
disk_system_id diskSystemID, const char *name, const char *parameters)
|
||||
{
|
||||
return new(nothrow) KInitializeJob(partitionID, diskSystemID, name,
|
||||
parameters);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateUninitializeJob(partition_id partitionID)
|
||||
{
|
||||
return new(nothrow) KUninitializeJob(partitionID);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateCreateChildJob(partition_id partitionID,
|
||||
partition_id childID, off_t offset, off_t size, const char *type,
|
||||
const char *parameters)
|
||||
{
|
||||
return new(nothrow) KCreateChildJob(partitionID, childID, offset, size,
|
||||
type, parameters);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateDeleteChildJob(partition_id parentID,
|
||||
partition_id partitionID)
|
||||
{
|
||||
return new(nothrow) KDeleteChildJob(parentID, partitionID);
|
||||
}
|
||||
|
||||
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobFactory::CreateScanPartitionJob(partition_id partitionID)
|
||||
{
|
||||
return new(nothrow) KScanPartitionJob(partitionID);
|
||||
}
|
||||
|
||||
@@ -1,487 +0,0 @@
|
||||
// KDiskDeviceJobGenerator.cpp
|
||||
|
||||
#include "KDiskDevice.h"
|
||||
#include "KDiskDeviceJob.h"
|
||||
#include "KDiskDeviceJobFactory.h"
|
||||
#include "KDiskDeviceJobQueue.h"
|
||||
#include "KDiskDeviceJobGenerator.h"
|
||||
#include "KDiskDeviceUtils.h"
|
||||
#include "KDiskSystem.h"
|
||||
#include "KShadowPartition.h"
|
||||
|
||||
// move_info
|
||||
struct KDiskDeviceJobGenerator::move_info {
|
||||
KPartition *partition;
|
||||
off_t position;
|
||||
off_t target_position;
|
||||
off_t size;
|
||||
};
|
||||
|
||||
// constructor
|
||||
KDiskDeviceJobGenerator::KDiskDeviceJobGenerator(
|
||||
KDiskDeviceJobFactory *jobFactory, KDiskDevice *device,
|
||||
KDiskDeviceJobQueue *jobQueue)
|
||||
: fJobFactory(jobFactory),
|
||||
fDevice(device),
|
||||
fJobQueue(jobQueue),
|
||||
fMoveInfos(NULL),
|
||||
fMoveInfoCount(0),
|
||||
fPartitionIDs(NULL),
|
||||
fPartitionIDCount(0)
|
||||
{
|
||||
if (fDevice && !fJobQueue) {
|
||||
fJobQueue = new(nothrow) KDiskDeviceJobQueue(fDevice);
|
||||
if (fDevice->ShadowPartition()) {
|
||||
fMoveInfoCount = max(fDevice->CountDescendants(),
|
||||
fDevice->ShadowPartition()->CountDescendants());
|
||||
}
|
||||
fMoveInfos = new(nothrow) move_info[fMoveInfoCount];
|
||||
fPartitionIDs = new(nothrow) partition_id[fMoveInfoCount];
|
||||
}
|
||||
}
|
||||
|
||||
// destructor
|
||||
KDiskDeviceJobGenerator::~KDiskDeviceJobGenerator()
|
||||
{
|
||||
delete[] fMoveInfos;
|
||||
delete[] fPartitionIDs;
|
||||
delete fJobQueue;
|
||||
}
|
||||
|
||||
// JobFactory
|
||||
KDiskDeviceJobFactory *
|
||||
KDiskDeviceJobGenerator::JobFactory() const
|
||||
{
|
||||
return fJobFactory;
|
||||
}
|
||||
|
||||
// Device
|
||||
KDiskDevice *
|
||||
KDiskDeviceJobGenerator::Device() const
|
||||
{
|
||||
return fDevice;
|
||||
}
|
||||
|
||||
// JobQueue
|
||||
KDiskDeviceJobQueue *
|
||||
KDiskDeviceJobGenerator::JobQueue() const
|
||||
{
|
||||
return fJobQueue;
|
||||
}
|
||||
|
||||
// DetachJobQueue
|
||||
KDiskDeviceJobQueue *
|
||||
KDiskDeviceJobGenerator::DetachJobQueue()
|
||||
{
|
||||
KDiskDeviceJobQueue *jobQueue = fJobQueue;
|
||||
fJobQueue = NULL;
|
||||
return jobQueue;
|
||||
}
|
||||
|
||||
// GenerateJobs
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::GenerateJobs()
|
||||
{
|
||||
// check parameters
|
||||
if (!fJobFactory || !fDevice || !fJobQueue || !fMoveInfos || !fPartitionIDs
|
||||
|| fJobQueue->Device() != fDevice || !fDevice->ShadowPartition()) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
// 1) Generate jobs for all physical partitions that don't have an
|
||||
// associated shadow partition, i.e. those that shall be deleted.
|
||||
// 2) Generate uninitialize jobs for all partition whose initialization
|
||||
// changes, also those that shall be initialized with a disk system.
|
||||
// This simplifies moving and resizing.
|
||||
status_t error = _GenerateCleanupJobs(fDevice);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// Generate jobs that move and resize the remaining physical partitions
|
||||
// to their final position/size.
|
||||
error = _GeneratePlacementJobs(fDevice);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// Generate the remaining jobs in one run: initialization, creation of
|
||||
// partitions, and changing of name, content name, type, parameters, and
|
||||
// content parameters.
|
||||
error = _GenerateRemainingJobs(NULL, fDevice->ShadowPartition());
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _AddJob
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_AddJob(KDiskDeviceJob *job)
|
||||
{
|
||||
if (!job)
|
||||
return B_NO_MEMORY;
|
||||
if (!fJobQueue->AddJob(job)) {
|
||||
delete job;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _GenerateCleanupJobs
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_GenerateCleanupJobs(KPartition *partition)
|
||||
{
|
||||
// TODO: Depending on how this shall be handled, we might want to unmount
|
||||
// all descendants of a partition to be uninitialized or removed.
|
||||
if (KPartition *shadow = partition->ShadowPartition()) {
|
||||
if (shadow->ChangeFlags() & B_PARTITION_CHANGED_INITIALIZATION) {
|
||||
// partition changes initialization
|
||||
status_t error = _AddJob(fJobFactory->CreateUninitializeJob(
|
||||
partition->ID()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
} else {
|
||||
// recurse
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) {
|
||||
status_t error = _GenerateCleanupJobs(child);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
} else if (KPartition *parent = partition->Parent()) {
|
||||
// create job and add it to the queue
|
||||
status_t error = _AddJob(fJobFactory->CreateDeleteChildJob(
|
||||
parent->ID(), partition->ID()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _GeneratePlacementJobs
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_GeneratePlacementJobs(KPartition *partition)
|
||||
{
|
||||
if (KPartition *shadow = partition->ShadowPartition()) {
|
||||
// Don't resize/move partitions that have an unrecognized contents.
|
||||
// They must have been uninitialized before.
|
||||
if (shadow->Status() == B_PARTITION_UNRECOGNIZED
|
||||
&& (shadow->Size() != partition->Size()
|
||||
|| shadow->Offset() != partition->Offset())) {
|
||||
return B_ERROR;
|
||||
}
|
||||
if (shadow->Size() > partition->Size()) {
|
||||
// size grows: resize first
|
||||
status_t error = _GenerateResizeJob(partition);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
// place the children
|
||||
status_t error = _GenerateChildPlacementJobs(partition);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
if (shadow->Size() < partition->Size()) {
|
||||
// size shrinks: resize now
|
||||
status_t error = _GenerateResizeJob(partition);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _GenerateResizeJob
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_GenerateResizeJob(KPartition *partition)
|
||||
{
|
||||
KPartition *shadow = partition->ShadowPartition();
|
||||
if (!shadow)
|
||||
return B_BAD_VALUE;
|
||||
if (!partition->Parent())
|
||||
return B_ERROR;
|
||||
return _AddJob(fJobFactory->CreateResizeJob(partition->Parent()->ID(),
|
||||
partition->ID(),
|
||||
shadow->Size()));
|
||||
}
|
||||
|
||||
// _GenerateChildPlacementJobs
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_GenerateChildPlacementJobs(KPartition *partition)
|
||||
{
|
||||
KPartition *shadow = partition->ShadowPartition();
|
||||
// nothing to do, if the partition contains no partitioning system or
|
||||
// shall be re-initialized
|
||||
if (!shadow->DiskSystem()
|
||||
|| (shadow->ChangeFlags() & B_PARTITION_CHANGED_INITIALIZATION)) {
|
||||
return B_OK;
|
||||
}
|
||||
// first resize all children that shall shrink and place their descendants
|
||||
int32 childCount = 0;
|
||||
int32 moveForth = 0;
|
||||
int32 moveBack = 0;
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) {
|
||||
if (KPartition *childShadow = child->ShadowPartition()) {
|
||||
// add a move_info for the child
|
||||
move_info &info = fMoveInfos[childCount];
|
||||
childCount++;
|
||||
info.partition = child;
|
||||
info.position = child->Offset();
|
||||
info.target_position = childShadow->Offset();
|
||||
info.size = child->Size();
|
||||
if (info.position < info.target_position)
|
||||
moveForth++;
|
||||
else if (info.position > info.target_position)
|
||||
moveBack++;
|
||||
// resize the child, if it shall shrink
|
||||
if (childShadow->Size() < child->Size()) {
|
||||
status_t error = _GeneratePlacementJobs(child);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
info.size = childShadow->Size();
|
||||
}
|
||||
}
|
||||
}
|
||||
// sort the move infos
|
||||
if (childCount > 0 && moveForth + moveBack > 0) {
|
||||
qsort(fMoveInfos, childCount, sizeof(move_info),
|
||||
_CompareMoveInfoPosition);
|
||||
}
|
||||
// move the children to their final positions
|
||||
while (moveForth + moveBack > 0) {
|
||||
int32 moved = 0;
|
||||
if (moveForth < moveBack) {
|
||||
// move children back
|
||||
for (int32 i = 0; i < childCount; i++) {
|
||||
move_info &info = fMoveInfos[i];
|
||||
if (info.position > info.target_position) {
|
||||
if (i == 0
|
||||
|| info.target_position >= fMoveInfos[i - 1].position
|
||||
+ fMoveInfos[i - 1].size) {
|
||||
// check OK -- the partition wouldn't be moved before
|
||||
// the end of the preceding one
|
||||
status_t error = _GenerateMoveJob(info.partition);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
info.position = info.target_position;
|
||||
moved++;
|
||||
moveBack--;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// move children forth
|
||||
for (int32 i = childCount - 1; i >= 0; i--) {
|
||||
move_info &info = fMoveInfos[i];
|
||||
if (info.position > info.target_position) {
|
||||
if (i == childCount - 1
|
||||
|| info.target_position + info.size
|
||||
<= fMoveInfos[i - 1].position) {
|
||||
// check OK -- the partition wouldn't be moved before
|
||||
// the end of the preceding one
|
||||
status_t error = _GenerateMoveJob(info.partition);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
info.position = info.target_position;
|
||||
moved++;
|
||||
moveForth--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// terminate, if no partition could be moved
|
||||
if (moved == 0)
|
||||
return B_ERROR;
|
||||
}
|
||||
// now resize all children that shall grow/keep their size and place
|
||||
// their descendants
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) {
|
||||
if (KPartition *childShadow = child->ShadowPartition()) {
|
||||
if (childShadow->Size() >= child->Size()) {
|
||||
status_t error = _GeneratePlacementJobs(child);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _GenerateMoveJob
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_GenerateMoveJob(KPartition *partition)
|
||||
{
|
||||
KPartition *shadow = partition->ShadowPartition();
|
||||
if (!shadow)
|
||||
return B_BAD_VALUE;
|
||||
if (!partition->Parent())
|
||||
return B_ERROR;
|
||||
// collect all descendants whose contents need to be moved
|
||||
fPartitionIDCount = 0;;
|
||||
status_t error = _CollectContentsToMove(partition);
|
||||
if (error != B_OK)
|
||||
return B_OK;
|
||||
// add the job
|
||||
return _AddJob(fJobFactory->CreateMoveJob(partition->Parent()->ID(),
|
||||
partition->ID(),
|
||||
shadow->Offset(), fPartitionIDs,
|
||||
fPartitionIDCount));
|
||||
}
|
||||
|
||||
// _CollectContentsToMove
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_CollectContentsToMove(KPartition *partition)
|
||||
{
|
||||
KPartition *shadow = partition->ShadowPartition();
|
||||
if (!shadow)
|
||||
return B_OK;
|
||||
if (shadow->Status() == B_PARTITION_UNRECOGNIZED)
|
||||
return B_ERROR;
|
||||
// if the partition has contents, push its ID
|
||||
if (shadow->DiskSystem()
|
||||
&& !(shadow->ChangeFlags() & B_PARTITION_CHANGED_INITIALIZATION)) {
|
||||
_PushPartitionID(partition->ID());
|
||||
}
|
||||
// recurse
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++) {
|
||||
status_t error = _CollectContentsToMove(child);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _GenerateRemainingJobs
|
||||
status_t
|
||||
KDiskDeviceJobGenerator::_GenerateRemainingJobs(KShadowPartition *parent,
|
||||
KShadowPartition *partition)
|
||||
{
|
||||
KPhysicalPartition *physicalPartition = partition->PhysicalPartition();
|
||||
// get correct ID of partition and parent partition
|
||||
partition_id partitionID = (physicalPartition ? physicalPartition->ID()
|
||||
: partition->ID());
|
||||
partition_id parentID = -1;
|
||||
if (parent) {
|
||||
parentID = (parent->PhysicalPartition()
|
||||
? parent->PhysicalPartition()->ID() : parent->ID());
|
||||
}
|
||||
// create the partition, if not existing yet
|
||||
if (!physicalPartition) {
|
||||
if (!parent)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _AddJob(fJobFactory->CreateCreateChildJob(
|
||||
parentID, partitionID, partition->Offset(), partition->Size(),
|
||||
partition->Type(), partition->Parameters()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
} else {
|
||||
// partition already exists: set non-content properties
|
||||
// name
|
||||
if ((partition->ChangeFlags() & B_PARTITION_CHANGED_NAME)
|
||||
|| compare_string(partition->Name(), physicalPartition->Name())) {
|
||||
if (!parent)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _AddJob(fJobFactory->CreateSetNameJob(
|
||||
parentID, partitionID, partition->Name()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
// type
|
||||
if ((partition->ChangeFlags() & B_PARTITION_CHANGED_TYPE)
|
||||
|| compare_string(partition->Type(), physicalPartition->Type())) {
|
||||
if (!parent)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _AddJob(fJobFactory->CreateSetTypeJob(
|
||||
parentID, partitionID, partition->Type()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
// parameters
|
||||
if ((partition->ChangeFlags() & B_PARTITION_CHANGED_PARAMETERS)
|
||||
|| compare_string(partition->Parameters(),
|
||||
physicalPartition->Parameters())) {
|
||||
if (!parent)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _AddJob(fJobFactory->CreateSetParametersJob(
|
||||
parentID, partitionID, partition->Parameters()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
if (partition->DiskSystem()) {
|
||||
// initialize the partition, if required
|
||||
if (partition->ChangeFlags() & B_PARTITION_CHANGED_INITIALIZATION) {
|
||||
status_t error = _AddJob(fJobFactory->CreateInitializeJob(
|
||||
partitionID, partition->DiskSystem()->ID(),
|
||||
partition->ContentName(), partition->ContentParameters()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
} else {
|
||||
// partition not (re-)initialized, set content properties
|
||||
// content name
|
||||
if ((partition->ChangeFlags() & B_PARTITION_CHANGED_NAME)
|
||||
|| compare_string(partition->ContentName(),
|
||||
physicalPartition->ContentName())) {
|
||||
status_t error = _AddJob(fJobFactory->CreateSetContentNameJob(
|
||||
partitionID, partition->ContentName()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
// content parameters
|
||||
if ((partition->ChangeFlags() & B_PARTITION_CHANGED_PARAMETERS)
|
||||
|| compare_string(partition->ContentParameters(),
|
||||
physicalPartition->ContentParameters())) {
|
||||
status_t error = _AddJob(
|
||||
fJobFactory->CreateSetContentParametersJob(
|
||||
partitionID, partition->ContentParameters()));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
// defragment
|
||||
if (partition->ChangeFlags()
|
||||
& B_PARTITION_CHANGED_DEFRAGMENTATION) {
|
||||
status_t error = _AddJob(fJobFactory->CreateDefragmentJob(
|
||||
partitionID));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
// check / repair
|
||||
bool repair = (partition->ChangeFlags()
|
||||
& B_PARTITION_CHANGED_REPAIR);
|
||||
if ((partition->ChangeFlags() & B_PARTITION_CHANGED_CHECK)
|
||||
|| repair) {
|
||||
status_t error = _AddJob(fJobFactory->CreateRepairJob(
|
||||
partitionID, repair));
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
// recurse
|
||||
for (int32 i = 0; KPartition *_child = partition->ChildAt(i); i++) {
|
||||
// ToDo: was:
|
||||
// KShadowPartition *child = dynamic_cast<KShadowPartition *>(_child);
|
||||
KShadowPartition *child = static_cast<KShadowPartition *>(_child);
|
||||
if (!child)
|
||||
return B_BAD_VALUE;
|
||||
status_t error = _GenerateRemainingJobs(partition, child);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _PushPartitionID
|
||||
void
|
||||
KDiskDeviceJobGenerator::_PushPartitionID(partition_id id)
|
||||
{
|
||||
fPartitionIDs[fPartitionIDCount++] = id;
|
||||
}
|
||||
|
||||
// _CompareMoveInfoOffset
|
||||
int
|
||||
KDiskDeviceJobGenerator::_CompareMoveInfoPosition(const void *_a,
|
||||
const void *_b)
|
||||
{
|
||||
const move_info *a = static_cast<const move_info *>(_a);
|
||||
const move_info *b = static_cast<const move_info *>(_b);
|
||||
if (a->position < b->position)
|
||||
return -1;
|
||||
if (a->position > b->position)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
// KDiskDeviceJobGenerator.h
|
||||
|
||||
#ifndef _K_DISK_DEVICE_JOB_GENERATOR_H
|
||||
#define _K_DISK_DEVICE_JOB_GENERATOR_H
|
||||
|
||||
#include "disk_device_manager.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KDiskDevice;
|
||||
class KDiskDeviceJob;
|
||||
class KDiskDeviceJobFactory;
|
||||
class KDiskDeviceJobQueue;
|
||||
class KPartition;
|
||||
class KPhysicalPartition;
|
||||
class KShadowPartition;
|
||||
|
||||
class KDiskDeviceJobGenerator {
|
||||
public:
|
||||
KDiskDeviceJobGenerator(KDiskDeviceJobFactory *jobFactory,
|
||||
KDiskDevice *device,
|
||||
KDiskDeviceJobQueue *jobQueue = NULL);
|
||||
~KDiskDeviceJobGenerator();
|
||||
|
||||
KDiskDeviceJobFactory *JobFactory() const;
|
||||
KDiskDevice *Device() const;
|
||||
KDiskDeviceJobQueue *JobQueue() const;
|
||||
|
||||
KDiskDeviceJobQueue *DetachJobQueue();
|
||||
|
||||
status_t GenerateJobs();
|
||||
|
||||
private:
|
||||
struct move_info;
|
||||
|
||||
status_t _AddJob(KDiskDeviceJob *job);
|
||||
|
||||
status_t _GenerateCleanupJobs(KPartition *partition);
|
||||
status_t _GeneratePlacementJobs(KPartition *partition);
|
||||
status_t _GenerateResizeJob(KPartition *partition);
|
||||
status_t _GenerateChildPlacementJobs(KPartition *partition);
|
||||
status_t _GenerateMoveJob(KPartition *partition);
|
||||
status_t _CollectContentsToMove(KPartition *partition);
|
||||
status_t _GenerateRemainingJobs(KShadowPartition *parent,
|
||||
KShadowPartition *partition);
|
||||
|
||||
void _PushPartitionID(partition_id id);
|
||||
static int _CompareMoveInfoPosition(const void *_a, const void *_b);
|
||||
|
||||
KDiskDeviceJobFactory *fJobFactory;
|
||||
KDiskDevice *fDevice;
|
||||
KDiskDeviceJobQueue *fJobQueue;
|
||||
move_info *fMoveInfos;
|
||||
int32 fMoveInfoCount;
|
||||
partition_id *fPartitionIDs;
|
||||
int32 fPartitionIDCount;
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KDiskDeviceJobGenerator;
|
||||
|
||||
#endif // _K_DISK_DEVICE_JOB_GENERATOR_H
|
||||
@@ -1,361 +0,0 @@
|
||||
// KDiskDeviceJobQueue.cpp
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <Vector.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <util/kernel_cpp.h>
|
||||
|
||||
#include "KDiskDevice.h"
|
||||
#include "KDiskDeviceJob.h"
|
||||
#include "KDiskDeviceJobQueue.h"
|
||||
#include "KDiskDeviceManager.h"
|
||||
#include "KDiskDeviceUtils.h"
|
||||
|
||||
// debugging
|
||||
//#define DBG(x)
|
||||
#define DBG(x) x
|
||||
#define OUT dprintf
|
||||
|
||||
using namespace std;
|
||||
|
||||
// flags
|
||||
enum {
|
||||
JOB_QUEUE_EXECUTING = 0x01,
|
||||
JOB_QUEUE_CANCELED = 0x02,
|
||||
JOB_QUEUE_REVERSE = 0x04,
|
||||
JOB_QUEUE_PAUSED = 0x08,
|
||||
JOB_QUEUE_PAUSE_REQUESTED = 0x10,
|
||||
};
|
||||
|
||||
struct KDiskDeviceJobQueue::JobQueue : Vector<KDiskDeviceJob*> {};
|
||||
|
||||
// constructor
|
||||
KDiskDeviceJobQueue::KDiskDeviceJobQueue(KDiskDevice *device)
|
||||
: fDevice(NULL),
|
||||
fActiveJob(0),
|
||||
fJobs(NULL),
|
||||
fFlags(0),
|
||||
fThread(-1),
|
||||
fSyncSemaphore(-1)
|
||||
{
|
||||
fJobs = new(nothrow) JobQueue;
|
||||
SetDevice(device);
|
||||
}
|
||||
|
||||
// destructor
|
||||
KDiskDeviceJobQueue::~KDiskDeviceJobQueue()
|
||||
{
|
||||
// Delete the semaphore. This awakes our thread in case it is paused --
|
||||
// that shouldn't happen, though.
|
||||
if (fSyncSemaphore >= 0)
|
||||
delete_sem(fSyncSemaphore);
|
||||
// The thread should not run or is just deleting us via the manager
|
||||
// method DeleteJobQueue(). At any rate, fThread should be unset.
|
||||
if (fThread >= 0) {
|
||||
// something's weird
|
||||
DBG(OUT("WARNING: KDiskDeviceJobQueue::~KDiskDeviceJobQueue(): jobber "
|
||||
" thread is still running!\n"));
|
||||
}
|
||||
// delete the jobs and the queue
|
||||
if (fJobs) {
|
||||
int32 count = fJobs->Count();
|
||||
for (int32 i = 0; i < count; i++)
|
||||
delete fJobs->ElementAt(i);
|
||||
delete fJobs;
|
||||
}
|
||||
// unset the device
|
||||
SetDevice(NULL);
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
status_t
|
||||
KDiskDeviceJobQueue::InitCheck() const
|
||||
{
|
||||
return (fJobs ? B_OK : B_NO_MEMORY);
|
||||
}
|
||||
|
||||
// SetDevice
|
||||
void
|
||||
KDiskDeviceJobQueue::SetDevice(KDiskDevice *device)
|
||||
{
|
||||
// unset the old device
|
||||
if (fDevice) {
|
||||
fDevice->Unregister();
|
||||
fDevice = NULL;
|
||||
}
|
||||
// set the new one
|
||||
if (device) {
|
||||
fDevice = device;
|
||||
fDevice->Register();
|
||||
}
|
||||
}
|
||||
|
||||
// Device
|
||||
BPrivate::DiskDevice::KDiskDevice *
|
||||
KDiskDeviceJobQueue::Device() const
|
||||
{
|
||||
return fDevice;
|
||||
}
|
||||
|
||||
// ActiveJobIndex
|
||||
int32
|
||||
KDiskDeviceJobQueue::ActiveJobIndex() const
|
||||
{
|
||||
return fActiveJob;
|
||||
}
|
||||
|
||||
// ActiveJob
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobQueue::ActiveJob() const
|
||||
{
|
||||
return JobAt(fActiveJob);
|
||||
}
|
||||
|
||||
// AddJob
|
||||
bool
|
||||
KDiskDeviceJobQueue::AddJob(KDiskDeviceJob *job)
|
||||
{
|
||||
if (InitCheck() != B_OK || IsExecuting() || !job || job->JobQueue())
|
||||
return false;
|
||||
status_t error = fJobs->PushBack(job);
|
||||
if (error == B_OK)
|
||||
job->SetJobQueue(this);
|
||||
return (error == B_OK);
|
||||
}
|
||||
|
||||
// RemoveJob
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobQueue::RemoveJob(int32 index)
|
||||
{
|
||||
if (InitCheck() != B_OK || IsExecuting() || index < 0
|
||||
|| index >= fJobs->Count()) {
|
||||
return NULL;
|
||||
}
|
||||
KDiskDeviceJob *job = fJobs->ElementAt(index);
|
||||
fJobs->Erase(index);
|
||||
job->SetJobQueue(NULL);
|
||||
return job;
|
||||
}
|
||||
|
||||
// RemoveJob
|
||||
bool
|
||||
KDiskDeviceJobQueue::RemoveJob(KDiskDeviceJob *job)
|
||||
{
|
||||
if (InitCheck() != B_OK || IsExecuting() || !job
|
||||
|| job->JobQueue() != this) {
|
||||
return false;
|
||||
}
|
||||
return RemoveJob(fJobs->IndexOf(job));
|
||||
}
|
||||
|
||||
// JobAt
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceJobQueue::JobAt(int32 index) const
|
||||
{
|
||||
if (InitCheck() != B_OK || index < 0 || index >= fJobs->Count())
|
||||
return NULL;
|
||||
return fJobs->ElementAt(index);
|
||||
}
|
||||
|
||||
// CountJobs
|
||||
int32
|
||||
KDiskDeviceJobQueue::CountJobs() const
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return 0;
|
||||
return fJobs->Count();
|
||||
}
|
||||
|
||||
// Execute
|
||||
status_t
|
||||
KDiskDeviceJobQueue::Execute()
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
if (IsExecuting())
|
||||
return B_BAD_VALUE;
|
||||
// create a synchronization semaphore
|
||||
fSyncSemaphore = create_sem(0, "disk device job queue sync");
|
||||
if (fSyncSemaphore < 0)
|
||||
return fSyncSemaphore;
|
||||
// spawn a thread and run it
|
||||
fThread = spawn_kernel_thread(_ThreadEntry, "disk device jobber",
|
||||
B_NORMAL_PRIORITY, this);
|
||||
if (fThread < 0) {
|
||||
delete_sem(fSyncSemaphore);
|
||||
fSyncSemaphore = -1;
|
||||
return fThread;
|
||||
}
|
||||
fFlags |= JOB_QUEUE_EXECUTING;
|
||||
resume_thread(fThread);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Cancel
|
||||
status_t
|
||||
KDiskDeviceJobQueue::Cancel(bool reverse)
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
if (!IsExecuting() || IsCanceled())
|
||||
return B_BAD_VALUE;
|
||||
KDiskDeviceJob *job = ActiveJob();
|
||||
if (!job)
|
||||
return B_ERROR;
|
||||
// check, if the active job allows canceling
|
||||
if (!(job->InterruptProperties() & B_DISK_DEVICE_JOB_CAN_CANCEL))
|
||||
return B_BAD_VALUE;
|
||||
if (reverse && !(job->InterruptProperties()
|
||||
& B_DISK_DEVICE_JOB_REVERSE_ON_CANCEL)) {
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
// update the flags
|
||||
fFlags |= JOB_QUEUE_CANCELED;
|
||||
if (reverse)
|
||||
fFlags |= JOB_QUEUE_REVERSE;
|
||||
// let the thread continue, if paused
|
||||
if (IsPaused() || IsPauseRequested())
|
||||
Continue();
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Pause
|
||||
status_t
|
||||
KDiskDeviceJobQueue::Pause()
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
if (!IsExecuting() || IsCanceled() || IsPaused() || IsPauseRequested())
|
||||
return B_BAD_VALUE;
|
||||
fFlags |= JOB_QUEUE_PAUSE_REQUESTED;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Continue
|
||||
status_t
|
||||
KDiskDeviceJobQueue::Continue()
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
if (!IsExecuting() || !(IsPaused() || IsPauseRequested()))
|
||||
return B_BAD_VALUE;
|
||||
if (IsPaused()) {
|
||||
fFlags &= ~(uint32)JOB_QUEUE_PAUSED;
|
||||
release_sem(fSyncSemaphore);
|
||||
} else
|
||||
fFlags &= ~(uint32)JOB_QUEUE_PAUSE_REQUESTED;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// ReadyToPause
|
||||
sem_id
|
||||
KDiskDeviceJobQueue::ReadyToPause()
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return InitCheck();
|
||||
if (!IsExecuting() || !IsPauseRequested())
|
||||
return B_BAD_VALUE;
|
||||
fFlags &= ~(uint32)JOB_QUEUE_PAUSE_REQUESTED;
|
||||
fFlags |= JOB_QUEUE_PAUSED;
|
||||
return fSyncSemaphore;
|
||||
}
|
||||
|
||||
// IsExecuting
|
||||
bool
|
||||
KDiskDeviceJobQueue::IsExecuting() const
|
||||
{
|
||||
return (fFlags & JOB_QUEUE_EXECUTING);
|
||||
}
|
||||
|
||||
// IsCanceled
|
||||
bool
|
||||
KDiskDeviceJobQueue::IsCanceled() const
|
||||
{
|
||||
return (fFlags & JOB_QUEUE_CANCELED);
|
||||
}
|
||||
|
||||
// ShallReverse
|
||||
bool
|
||||
KDiskDeviceJobQueue::ShallReverse() const
|
||||
{
|
||||
return (fFlags & JOB_QUEUE_REVERSE);
|
||||
}
|
||||
|
||||
// IsPaused
|
||||
bool
|
||||
KDiskDeviceJobQueue::IsPaused() const
|
||||
{
|
||||
return (fFlags & JOB_QUEUE_PAUSED);
|
||||
}
|
||||
|
||||
// IsPauseRequested
|
||||
bool
|
||||
KDiskDeviceJobQueue::IsPauseRequested() const
|
||||
{
|
||||
return (fFlags & JOB_QUEUE_PAUSE_REQUESTED);
|
||||
}
|
||||
|
||||
// _ThreadLoop
|
||||
int32
|
||||
KDiskDeviceJobQueue::_ThreadLoop()
|
||||
{
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
// main loop: process all jobs
|
||||
bool failed = false;
|
||||
while (KDiskDeviceJob *activeJob = ActiveJob()) {
|
||||
manager->UpdateJobStatus(activeJob, B_DISK_DEVICE_JOB_IN_PROGRESS,
|
||||
true);
|
||||
status_t error = activeJob->Do();
|
||||
if (error == B_OK) {
|
||||
if (ManagerLocker locker = manager) {
|
||||
// if canceled, simply bail out -- this and all succeeding
|
||||
// jobs will be canceled
|
||||
if (IsCanceled())
|
||||
break;
|
||||
// if pause was requested ignore the request
|
||||
if (IsPauseRequested())
|
||||
Continue();
|
||||
// go to the next job
|
||||
fActiveJob++;
|
||||
} else
|
||||
break;
|
||||
// mark the job succeeded
|
||||
manager->UpdateJobStatus(activeJob, B_DISK_DEVICE_JOB_SUCCEEDED,
|
||||
true);
|
||||
} else {
|
||||
DBG(OUT("job failed: %s\n", strerror(error)));
|
||||
DBG(OUT(" message: %s\n", activeJob->ErrorMessage()));
|
||||
// job failed: this and all succeeding jobs will be marked failed
|
||||
failed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// All jobs that remain need to be marked failed or canceled.
|
||||
bool updatePartitions = false;
|
||||
for (int32 i = fActiveJob; KDiskDeviceJob *job = JobAt(i); i++) {
|
||||
manager->UpdateJobStatus(job, (failed ? B_DISK_DEVICE_JOB_FAILED
|
||||
: B_DISK_DEVICE_JOB_CANCELED),
|
||||
false);
|
||||
updatePartitions = true;
|
||||
}
|
||||
if (updatePartitions)
|
||||
manager->UpdateBusyPartitions(Device());
|
||||
// tell the manager, that we are done.
|
||||
if (ManagerLocker locker = manager) {
|
||||
fFlags &= ~(uint32)JOB_QUEUE_EXECUTING;
|
||||
fThread = -1;
|
||||
manager->DeleteJobQueue(this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// _ThreadEntry
|
||||
int32
|
||||
KDiskDeviceJobQueue::_ThreadEntry(void *data)
|
||||
{
|
||||
return static_cast<KDiskDeviceJobQueue*>(data)->_ThreadLoop();
|
||||
}
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
|
||||
|
||||
#include "KDiskDevice.h"
|
||||
#include "KDiskDeviceJob.h"
|
||||
#include "KDiskDeviceJobFactory.h"
|
||||
#include "KDiskDeviceJobQueue.h"
|
||||
#include "KDiskDeviceManager.h"
|
||||
#include "KDiskDeviceUtils.h"
|
||||
#include "KDiskSystem.h"
|
||||
@@ -66,13 +63,6 @@ struct GetDiskSystemID {
|
||||
}
|
||||
};
|
||||
|
||||
// GetJobID
|
||||
struct GetJobID {
|
||||
inline disk_job_id operator()(const KDiskDeviceJob *job) const
|
||||
{
|
||||
return job->ID();
|
||||
}
|
||||
};
|
||||
|
||||
// PartitionMap
|
||||
struct KDiskDeviceManager::PartitionMap : VectorMap<partition_id, KPartition*,
|
||||
@@ -97,15 +87,6 @@ struct KDiskDeviceManager::DiskSystemMap : VectorMap<disk_system_id,
|
||||
struct KDiskDeviceManager::PartitionSet : VectorSet<KPartition*> {
|
||||
};
|
||||
|
||||
// JobMap
|
||||
struct KDiskDeviceManager::JobMap : VectorMap<disk_job_id, KDiskDeviceJob*,
|
||||
VectorMapEntryStrategy::ImplicitKey<disk_job_id, KDiskDeviceJob*,
|
||||
GetJobID> > {
|
||||
};
|
||||
|
||||
// JobQueueVector
|
||||
struct KDiskDeviceManager::JobQueueVector : Vector<KDiskDeviceJobQueue*> {};
|
||||
|
||||
|
||||
static bool
|
||||
is_active_job_status(uint32 status)
|
||||
@@ -123,10 +104,7 @@ KDiskDeviceManager::KDiskDeviceManager()
|
||||
fDevices(new(nothrow) DeviceMap),
|
||||
fPartitions(new(nothrow) PartitionMap),
|
||||
fDiskSystems(new(nothrow) DiskSystemMap),
|
||||
fObsoletePartitions(new(nothrow) PartitionSet),
|
||||
fJobs(new(nothrow) JobMap),
|
||||
fJobQueues(new(nothrow) JobQueueVector),
|
||||
fJobFactory(new(nothrow) KDiskDeviceJobFactory)
|
||||
fObsoletePartitions(new(nothrow) PartitionSet)
|
||||
{
|
||||
if (InitCheck() != B_OK)
|
||||
return;
|
||||
@@ -184,19 +162,15 @@ KDiskDeviceManager::~KDiskDeviceManager()
|
||||
delete fDevices;
|
||||
delete fDiskSystems;
|
||||
delete fObsoletePartitions;
|
||||
delete fJobs;
|
||||
delete fJobQueues;
|
||||
delete fJobFactory;
|
||||
}
|
||||
|
||||
// InitCheck
|
||||
status_t
|
||||
KDiskDeviceManager::InitCheck() const
|
||||
{
|
||||
if (!fPartitions || !fDevices || !fDiskSystems || !fObsoletePartitions
|
||||
|| !fJobs || !fJobQueues || !fJobFactory) {
|
||||
if (!fPartitions || !fDevices || !fDiskSystems || !fObsoletePartitions)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
return (fLock.Sem() >= 0 ? B_OK : fLock.Sem());
|
||||
}
|
||||
|
||||
@@ -496,15 +470,15 @@ KDiskDeviceManager::WriteLockPartition(partition_id id)
|
||||
|
||||
// ScanPartition
|
||||
status_t
|
||||
KDiskDeviceManager::ScanPartition(KPartition* partition, bool async)
|
||||
KDiskDeviceManager::ScanPartition(KPartition* partition)
|
||||
{
|
||||
// TODO: This won't do. Locking the DDM while scanning the partition is not a
|
||||
// good idea. Even locking the device doesn't feels right. Marking the partition
|
||||
// good idea. Even locking the device doesn't feel right. Marking the partition
|
||||
// busy and passing the disk system a temporary clone of the partition_data
|
||||
// should work as well.
|
||||
if (DeviceWriteLocker deviceLocker = partition->Device()) {
|
||||
if (ManagerLocker locker = this)
|
||||
return _ScanPartition(partition, async);
|
||||
return _ScanPartition(partition, false);
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
@@ -513,8 +487,7 @@ KDiskDeviceManager::ScanPartition(KPartition* partition, bool async)
|
||||
|
||||
// CreateFileDevice
|
||||
partition_id
|
||||
KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated,
|
||||
bool async)
|
||||
KDiskDeviceManager::CreateFileDevice(const char *filePath, bool* newlyCreated)
|
||||
{
|
||||
if (!filePath)
|
||||
return B_BAD_VALUE;
|
||||
@@ -532,6 +505,7 @@ KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated,
|
||||
if ((device = FindFileDevice(filePath))) {
|
||||
if (newlyCreated)
|
||||
*newlyCreated = false;
|
||||
|
||||
return device->ID();
|
||||
}
|
||||
|
||||
@@ -553,10 +527,11 @@ KDiskDeviceManager::CreateFileDevice(const char *filePath, bool *newlyCreated,
|
||||
|
||||
// scan device
|
||||
if (error == B_OK) {
|
||||
_ScanPartition(device, async);
|
||||
_ScanPartition(device, false);
|
||||
|
||||
if (newlyCreated)
|
||||
*newlyCreated = true;
|
||||
|
||||
return device->ID();
|
||||
}
|
||||
|
||||
@@ -655,160 +630,6 @@ KDiskDeviceManager::DeletePartition(KPartition *partition)
|
||||
return false;
|
||||
}
|
||||
|
||||
// FindJob
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceManager::FindJob(disk_job_id id)
|
||||
{
|
||||
JobMap::Iterator it = fJobs->Find(id);
|
||||
if (it == fJobs->End())
|
||||
return NULL;
|
||||
return it->Value();
|
||||
}
|
||||
|
||||
// CountJobs
|
||||
int32
|
||||
KDiskDeviceManager::CountJobs()
|
||||
{
|
||||
return fJobs->Count();
|
||||
}
|
||||
|
||||
// NextJob
|
||||
KDiskDeviceJob *
|
||||
KDiskDeviceManager::NextJob(int32 *cookie)
|
||||
{
|
||||
if (!cookie)
|
||||
return NULL;
|
||||
JobMap::Iterator it = fJobs->FindClose(*cookie, false);
|
||||
if (it != fJobs->End()) {
|
||||
KDiskDeviceJob *job = it->Value();
|
||||
*cookie = job->ID() + 1;
|
||||
return job;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// AddJobQueue
|
||||
/*!
|
||||
The device must be write locked, the manager must be locked.
|
||||
*/
|
||||
status_t
|
||||
KDiskDeviceManager::AddJobQueue(KDiskDeviceJobQueue *jobQueue)
|
||||
{
|
||||
// check the parameter
|
||||
if (!jobQueue)
|
||||
return B_BAD_VALUE;
|
||||
if (jobQueue->InitCheck() != B_OK)
|
||||
return jobQueue->InitCheck();
|
||||
// add the queue
|
||||
status_t error = fJobQueues->PushBack(jobQueue);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
// add the queue's jobs
|
||||
int32 count = jobQueue->CountJobs();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
KDiskDeviceJob *job = jobQueue->JobAt(i);
|
||||
error = fJobs->Put(job->ID(), job);
|
||||
if (error != B_OK) {
|
||||
_RemoveJobQueue(jobQueue);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
// mark the jobs scheduled
|
||||
for (int32 i = 0; KDiskDeviceJob *job = jobQueue->JobAt(i); i++)
|
||||
_UpdateJobStatus(job, B_DISK_DEVICE_JOB_SCHEDULED, false);
|
||||
_UpdateBusyPartitions(jobQueue->Device());
|
||||
// start the execution of the queue
|
||||
error = jobQueue->Execute();
|
||||
if (error != B_OK) {
|
||||
// resuming the execution failed -- mark all jobs failed and
|
||||
// remove the queue
|
||||
for (int32 i = 0; KDiskDeviceJob *job = jobQueue->JobAt(i); i++)
|
||||
_UpdateJobStatus(job, B_DISK_DEVICE_JOB_FAILED, false);
|
||||
_RemoveJobQueue(jobQueue);
|
||||
_UpdateBusyPartitions(jobQueue->Device());
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// RemoveJobQueue
|
||||
status_t
|
||||
KDiskDeviceManager::RemoveJobQueue(KDiskDeviceJobQueue *jobQueue)
|
||||
{
|
||||
if (!jobQueue)
|
||||
return B_BAD_VALUE;
|
||||
if (jobQueue->InitCheck() != B_OK)
|
||||
return jobQueue->InitCheck();
|
||||
if (jobQueue->IsExecuting())
|
||||
return B_BAD_VALUE;
|
||||
return (_RemoveJobQueue(jobQueue)
|
||||
? (status_t)B_OK : (status_t)B_ENTRY_NOT_FOUND);
|
||||
}
|
||||
|
||||
// DeleteJobQueue
|
||||
status_t
|
||||
KDiskDeviceManager::DeleteJobQueue(KDiskDeviceJobQueue *jobQueue)
|
||||
{
|
||||
status_t error = RemoveJobQueue(jobQueue);
|
||||
if (error == B_OK)
|
||||
delete jobQueue;
|
||||
return error;
|
||||
}
|
||||
|
||||
// CountJobQueues
|
||||
int32
|
||||
KDiskDeviceManager::CountJobQueues()
|
||||
{
|
||||
return fJobQueues->Count();
|
||||
}
|
||||
|
||||
// NextJobQueue
|
||||
KDiskDeviceJobQueue *
|
||||
KDiskDeviceManager::NextJobQueue(int32 *cookie)
|
||||
{
|
||||
if (!cookie || *cookie < 0 || *cookie >= CountJobQueues())
|
||||
return NULL;
|
||||
return fJobQueues->ElementAt((*cookie)++);
|
||||
}
|
||||
|
||||
// JobFactory
|
||||
KDiskDeviceJobFactory *
|
||||
KDiskDeviceManager::JobFactory() const
|
||||
{
|
||||
return fJobFactory;
|
||||
}
|
||||
|
||||
// UpdateBusyPartitions
|
||||
status_t
|
||||
KDiskDeviceManager::UpdateBusyPartitions(KDiskDevice *device)
|
||||
{
|
||||
if (!device)
|
||||
return B_BAD_VALUE;
|
||||
if (DeviceWriteLocker deviceLocker = device) {
|
||||
if (ManagerLocker locker = this)
|
||||
return _UpdateBusyPartitions(device);
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// UpdateJobStatus
|
||||
status_t
|
||||
KDiskDeviceManager::UpdateJobStatus(KDiskDeviceJob *job, uint32 status,
|
||||
bool updateBusyPartitions)
|
||||
{
|
||||
// check parameters
|
||||
if (!job)
|
||||
return B_BAD_VALUE;
|
||||
KDiskDeviceJobQueue *jobQueue = job->JobQueue();
|
||||
KDiskDevice *device = (jobQueue ? jobQueue->Device() : NULL);
|
||||
if (!device)
|
||||
return B_BAD_VALUE;
|
||||
// lock device and manager
|
||||
if (DeviceWriteLocker deviceLocker = device) {
|
||||
if (ManagerLocker locker = this)
|
||||
return _UpdateJobStatus(job, status, updateBusyPartitions);
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// FindDiskSystem
|
||||
KDiskSystem *
|
||||
@@ -1038,26 +859,8 @@ KDiskDeviceManager::_RemoveDevice(KDiskDevice *device)
|
||||
&& PartitionRemoved(device));
|
||||
}
|
||||
|
||||
// _RemoveJobQueue
|
||||
bool
|
||||
KDiskDeviceManager::_RemoveJobQueue(KDiskDeviceJobQueue *jobQueue)
|
||||
{
|
||||
if (!jobQueue)
|
||||
return false;
|
||||
// find the job queue
|
||||
JobQueueVector::Iterator it = fJobQueues->Find(jobQueue);
|
||||
if (it == fJobQueues->End())
|
||||
return false;
|
||||
// remove the queue's jobs
|
||||
int32 count = jobQueue->CountJobs();
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
KDiskDeviceJob *job = jobQueue->JobAt(i);
|
||||
fJobs->Remove(job->ID());
|
||||
}
|
||||
fJobQueues->Erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// _UpdateBusyPartitions
|
||||
/*!
|
||||
The device must be write locked, the manager must be locked.
|
||||
@@ -1119,32 +922,8 @@ KDiskDeviceManager::_UpdateBusyPartitions(KDiskDevice *device)
|
||||
device->VisitEachDescendant(&visitor2);
|
||||
return B_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
// _UpdateJobStatus
|
||||
status_t
|
||||
KDiskDeviceManager::_UpdateJobStatus(KDiskDeviceJob *job, uint32 status,
|
||||
bool updateBusyPartitions)
|
||||
{
|
||||
// check parameters
|
||||
if (!job)
|
||||
return B_BAD_VALUE;
|
||||
KDiskDeviceJobQueue *jobQueue = job->JobQueue();
|
||||
KDiskDevice *device = (jobQueue ? jobQueue->Device() : NULL);
|
||||
if (!device)
|
||||
return B_BAD_VALUE;
|
||||
if (job->Status() == status)
|
||||
return B_OK;
|
||||
// check migration of a schedule/in progress to a terminal state
|
||||
// or vice versa
|
||||
updateBusyPartitions &= (is_active_job_status(job->Status())
|
||||
!= is_active_job_status(status));
|
||||
// set new state and update the partitions' busy flags
|
||||
job->SetStatus(status);
|
||||
if (updateBusyPartitions)
|
||||
return _UpdateBusyPartitions(device);
|
||||
// TODO: notifications
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// _Scan
|
||||
status_t
|
||||
@@ -1210,42 +989,148 @@ DBG(OUT(" found device: %s\n", path));
|
||||
status_t
|
||||
KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async)
|
||||
{
|
||||
// TODO: There's no reason why the manager needs to be locked anymore.
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// TODO: Reimplement asynchronous scanning, if we really need it.
|
||||
#if 0
|
||||
if (async) {
|
||||
// create a new job queue for the device
|
||||
KDiskDeviceJobQueue *jobQueue = new(nothrow) KDiskDeviceJobQueue;
|
||||
if (!jobQueue)
|
||||
return B_NO_MEMORY;
|
||||
jobQueue->SetDevice(partition->Device());
|
||||
|
||||
// create a job for scanning the device and add it to the job queue
|
||||
KDiskDeviceJob *job = fJobFactory->CreateScanPartitionJob(partition->ID());
|
||||
if (!job) {
|
||||
delete jobQueue;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
if (!jobQueue->AddJob(job)) {
|
||||
delete jobQueue;
|
||||
delete job;
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
// add the job queue
|
||||
status_t error = AddJobQueue(jobQueue);
|
||||
if (error != B_OK)
|
||||
delete jobQueue;
|
||||
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
KDiskDeviceJob *job = fJobFactory->CreateScanPartitionJob(partition->ID());
|
||||
if (job == NULL)
|
||||
return B_NO_MEMORY;
|
||||
// scan synchronously
|
||||
|
||||
status_t status = job->Do();
|
||||
UpdateBusyPartitions(partition->Device());
|
||||
if (!partition->Device()->HasMedia())
|
||||
return B_OK;
|
||||
|
||||
delete job;
|
||||
return status;
|
||||
status_t error = _ScanPartition(partition);
|
||||
|
||||
// mark all partitions un-busy
|
||||
// TODO: This is not quite correct here. Partitions are created marked "busy",
|
||||
// hence the one creating it should be responsible for clearing the flag, not
|
||||
// us.
|
||||
struct UnmarkBusyVisitor : KPartitionVisitor {
|
||||
virtual bool VisitPre(KPartition* partition)
|
||||
{
|
||||
partition->ClearFlags(B_PARTITION_BUSY
|
||||
| B_PARTITION_DESCENDANT_BUSY);
|
||||
return false;
|
||||
}
|
||||
} visitor;
|
||||
|
||||
partition->VisitEachDescendant(&visitor);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KDiskDeviceManager::_ScanPartition(KPartition *partition)
|
||||
{
|
||||
// the partition's device must be write-locked
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
if (partition->DiskSystem() != NULL) {
|
||||
// TODO: this is more or less a hack to allow rescanning a partition
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++)
|
||||
_ScanPartition(child);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
DBG(
|
||||
KPath partitionPath;
|
||||
partition->GetPath(&partitionPath);
|
||||
OUT("KDiskDeviceManager::_ScanPartition(%s)\n", partitionPath.Path());
|
||||
)
|
||||
|
||||
// publish the partition
|
||||
status_t error = B_OK;
|
||||
if (!partition->IsPublished()) {
|
||||
error = partition->PublishDevice();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
// find the disk system that returns the best priority for this partition
|
||||
float bestPriority = -1;
|
||||
KDiskSystem *bestDiskSystem = NULL;
|
||||
void *bestCookie = NULL;
|
||||
int32 itCookie = 0;
|
||||
while (KDiskSystem *diskSystem = LoadNextDiskSystem(&itCookie)) {
|
||||
DBG(OUT(" trying: %s\n", diskSystem->Name()));
|
||||
|
||||
void *cookie = NULL;
|
||||
float priority = diskSystem->Identify(partition, &cookie);
|
||||
|
||||
DBG(OUT(" returned: %ld/1000\n", int32(1000 * priority)));
|
||||
|
||||
if (priority >= 0 && priority > bestPriority) {
|
||||
// new best disk system
|
||||
if (bestDiskSystem) {
|
||||
bestDiskSystem->FreeIdentifyCookie(partition, bestCookie);
|
||||
bestDiskSystem->Unload();
|
||||
}
|
||||
bestPriority = priority;
|
||||
bestDiskSystem = diskSystem;
|
||||
bestCookie = cookie;
|
||||
} else {
|
||||
// disk system doesn't identify the partition or worse than our
|
||||
// current favorite
|
||||
if (priority >= 0)
|
||||
diskSystem->FreeIdentifyCookie(partition, cookie);
|
||||
diskSystem->Unload();
|
||||
}
|
||||
}
|
||||
|
||||
// now, if we have found a disk system, let it scan the partition
|
||||
if (bestDiskSystem) {
|
||||
DBG(OUT(" scanning with: %s\n", bestDiskSystem->Name()));
|
||||
error = bestDiskSystem->Scan(partition, bestCookie);
|
||||
bestDiskSystem->FreeIdentifyCookie(partition, bestCookie);
|
||||
if (error == B_OK) {
|
||||
partition->SetDiskSystem(bestDiskSystem);
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++)
|
||||
_ScanPartition(child);
|
||||
} else {
|
||||
// TODO: Handle the error.
|
||||
DBG(OUT(" scanning failed: %s\n", strerror(error)));
|
||||
}
|
||||
|
||||
// now we can safely unload the disk system -- it has been loaded by
|
||||
// the partition(s) and thus will not really be unloaded
|
||||
bestDiskSystem->Unload();
|
||||
} else {
|
||||
// contents not recognized
|
||||
// nothing to be done -- partitions are created as unrecognized
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -190,195 +190,7 @@ KDiskSystem::FreeContentCookie(KPartition *partition)
|
||||
}
|
||||
|
||||
|
||||
// GetSupportedOperations
|
||||
uint32
|
||||
KDiskSystem::GetSupportedOperations(KPartition* partition, uint32 mask)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// GetSupportedChildOperations
|
||||
uint32
|
||||
KDiskSystem::GetSupportedChildOperations(KPartition* child, uint32 mask)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// SupportsInitializingChild
|
||||
bool
|
||||
KDiskSystem::SupportsInitializingChild(KPartition *child,
|
||||
const char *diskSystem)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// IsSubSystemFor
|
||||
bool
|
||||
KDiskSystem::IsSubSystemFor(KPartition *partition)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateResize
|
||||
bool
|
||||
KDiskSystem::ValidateResize(KPartition *partition, off_t *size)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateResizeChild
|
||||
bool
|
||||
KDiskSystem::ValidateResizeChild(KPartition *child, off_t *size)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateMove
|
||||
bool
|
||||
KDiskSystem::ValidateMove(KPartition *partition, off_t *start)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateMoveChild
|
||||
bool
|
||||
KDiskSystem::ValidateMoveChild(KPartition *child, off_t *start)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetName
|
||||
bool
|
||||
KDiskSystem::ValidateSetName(KPartition *partition, char *name)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetContentName
|
||||
bool
|
||||
KDiskSystem::ValidateSetContentName(KPartition *partition, char *name)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetType
|
||||
bool
|
||||
KDiskSystem::ValidateSetType(KPartition *partition, const char *type)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetParameters
|
||||
bool
|
||||
KDiskSystem::ValidateSetParameters(KPartition *partition,
|
||||
const char *parameters)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetContentParameters
|
||||
bool
|
||||
KDiskSystem::ValidateSetContentParameters(KPartition *partition,
|
||||
const char *parameters)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateInitialize
|
||||
bool
|
||||
KDiskSystem::ValidateInitialize(KPartition *partition, char *name,
|
||||
const char *parameters)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ValidateCreateChild
|
||||
bool
|
||||
KDiskSystem::ValidateCreateChild(KPartition *partition, off_t *start,
|
||||
off_t *size, const char *type,
|
||||
const char *parameters, int32 *index)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// CountPartitionableSpaces
|
||||
int32
|
||||
KDiskSystem::CountPartitionableSpaces(KPartition *partition)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// GetPartitionableSpaces
|
||||
status_t
|
||||
KDiskSystem::GetPartitionableSpaces(KPartition *partition,
|
||||
partitionable_space_data *buffer,
|
||||
int32 count, int32 *actualCount)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
// GetNextSupportedType
|
||||
status_t
|
||||
KDiskSystem::GetNextSupportedType(KPartition *partition, int32 *cookie,
|
||||
char *type)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
// ShadowPartitionChanged
|
||||
status_t
|
||||
KDiskSystem::ShadowPartitionChanged(KPartition *partition, KPartition *child,
|
||||
uint32 operation)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
// GetTypeForContentType
|
||||
status_t
|
||||
KDiskSystem::GetTypeForContentType(const char *contentType, char *type)
|
||||
{
|
||||
// to be implemented by derived classes
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Defragment
|
||||
status_t
|
||||
@@ -513,6 +325,8 @@ KDiskSystem::DeleteChild(KPartition *child, KDiskDeviceJob *job)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
// LoadModule
|
||||
status_t
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <fs_interface.h>
|
||||
|
||||
#include "ddm_modules.h"
|
||||
#include "KDiskDeviceJob.h"
|
||||
//#include "KDiskDeviceJob.h"
|
||||
#include "KDiskDeviceUtils.h"
|
||||
#include "KFileSystem.h"
|
||||
#include "KPartition.h"
|
||||
@@ -97,97 +97,7 @@ KFileSystem::FreeContentCookie(KPartition *partition)
|
||||
}
|
||||
|
||||
|
||||
// GetSupportedOperations
|
||||
uint32
|
||||
KFileSystem::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;
|
||||
|
||||
if (!fModule->get_supported_operations)
|
||||
return (Flags() & mask);
|
||||
|
||||
return fModule->get_supported_operations(partition->PartitionData(), mask)
|
||||
& mask;
|
||||
}
|
||||
|
||||
|
||||
// ValidateResize
|
||||
bool
|
||||
KFileSystem::ValidateResize(KPartition *partition, off_t *size)
|
||||
{
|
||||
return (partition && size && partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_resize
|
||||
&& fModule->validate_resize(partition->PartitionData(), size));
|
||||
}
|
||||
|
||||
|
||||
// ValidateMove
|
||||
bool
|
||||
KFileSystem::ValidateMove(KPartition *partition, off_t *start)
|
||||
{
|
||||
return (partition && start && partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_move
|
||||
&& fModule->validate_move(partition->PartitionData(), start));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetContentName
|
||||
bool
|
||||
KFileSystem::ValidateSetContentName(KPartition *partition, char *name)
|
||||
{
|
||||
return (partition && name && partition->DiskSystem() == this
|
||||
&& fModule && fModule->validate_set_content_name
|
||||
&& fModule->validate_set_content_name(partition->PartitionData(),
|
||||
name));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetContentParameters
|
||||
bool
|
||||
KFileSystem::ValidateSetContentParameters(KPartition *partition,
|
||||
const char *parameters)
|
||||
{
|
||||
return (partition && partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_set_content_parameters
|
||||
&& fModule->validate_set_content_parameters(
|
||||
partition->PartitionData(), parameters));
|
||||
}
|
||||
|
||||
|
||||
// ValidateInitialize
|
||||
bool
|
||||
KFileSystem::ValidateInitialize(KPartition *partition, char *name,
|
||||
const char *parameters)
|
||||
{
|
||||
return (partition && fModule && fModule->validate_initialize
|
||||
&& fModule->validate_initialize(partition->PartitionData(), name,
|
||||
parameters));
|
||||
}
|
||||
|
||||
|
||||
// ShadowPartitionChanged
|
||||
status_t
|
||||
KFileSystem::ShadowPartitionChanged(KPartition *partition, KPartition *child,
|
||||
uint32 operation)
|
||||
{
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
if (!fModule)
|
||||
return B_ERROR;
|
||||
// If not implemented, we assume, that the file system doesn't have to
|
||||
// make any additional changes.
|
||||
if (!fModule->shadow_changed)
|
||||
return B_OK;
|
||||
return fModule->shadow_changed(partition->PartitionData(),
|
||||
child ? child->PartitionData() : NULL, operation);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Defragment
|
||||
status_t
|
||||
@@ -277,6 +187,8 @@ KFileSystem::Initialize(KPartition *partition, const char *name,
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
// LoadModule
|
||||
status_t
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include <ddm_modules.h>
|
||||
#include <KDiskDevice.h>
|
||||
#include <KDiskDeviceJob.h>
|
||||
//#include <KDiskDeviceJob.h>
|
||||
#include <KDiskDeviceManager.h>
|
||||
#include <KDiskDeviceUtils.h>
|
||||
#include <KPartition.h>
|
||||
@@ -127,301 +127,7 @@ KPartitioningSystem::FreeContentCookie(KPartition *partition)
|
||||
}
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
/*! Check whether the child partition managed by this partitioning system can
|
||||
be initialized with the given disk system.
|
||||
*/
|
||||
bool
|
||||
KPartitioningSystem::SupportsInitializingChild(KPartition *child,
|
||||
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
|
||||
//! 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
|
||||
&& fModule->is_sub_system_for(partition->PartitionData()));
|
||||
}
|
||||
|
||||
|
||||
// ValidateResize
|
||||
//! Validates parameters for resizing a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateResize(KPartition *partition, off_t *size)
|
||||
{
|
||||
return (partition && size && partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_resize
|
||||
&& fModule->validate_resize(partition->PartitionData(), size));
|
||||
}
|
||||
|
||||
|
||||
// ValidateResizeChild
|
||||
//! Validates parameters for resizing a child partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateResizeChild(KPartition *child, off_t *size)
|
||||
{
|
||||
return (child && size && child->Parent()
|
||||
&& child->ParentDiskSystem() == this && fModule
|
||||
&& fModule->validate_resize_child
|
||||
&& fModule->validate_resize_child(child->Parent()->PartitionData(),
|
||||
child->PartitionData(), size));
|
||||
}
|
||||
|
||||
|
||||
// ValidateMove
|
||||
//! Validates parameters for moving a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateMove(KPartition *partition, off_t *start)
|
||||
{
|
||||
return (partition && start && partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_move
|
||||
&& fModule->validate_move(partition->PartitionData(), start));
|
||||
}
|
||||
|
||||
|
||||
// ValidateMoveChild
|
||||
//! Validates parameters for moving a child partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateMoveChild(KPartition *child, off_t *start)
|
||||
{
|
||||
return (child && start && child->Parent()
|
||||
&& child->ParentDiskSystem() == this && fModule
|
||||
&& fModule->validate_move_child
|
||||
&& fModule->validate_move_child(child->Parent()->PartitionData(),
|
||||
child->PartitionData(), start));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetName
|
||||
//! Validates parameters for setting name of a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateSetName(KPartition *partition, char *name)
|
||||
{
|
||||
return (partition && name && partition->Parent()
|
||||
&& partition->ParentDiskSystem() == this && fModule
|
||||
&& fModule->validate_set_name
|
||||
&& fModule->validate_set_name(partition->PartitionData(), name));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetContentName
|
||||
//! Validates parameters for setting name of the content of a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateSetContentName(KPartition *partition, char *name)
|
||||
{
|
||||
return (partition && name && partition->DiskSystem() == this
|
||||
&& fModule && fModule->validate_set_content_name
|
||||
&& fModule->validate_set_content_name(partition->PartitionData(),
|
||||
name));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetType
|
||||
//! Validates parameters for setting type of a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateSetType(KPartition *partition, const char *type)
|
||||
{
|
||||
return (partition && type && partition->ParentDiskSystem() == this
|
||||
&& fModule && fModule->validate_set_type
|
||||
&& fModule->validate_set_type(partition->PartitionData(), type));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetParameters
|
||||
//! Validates parameters for setting parameters of a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateSetParameters(KPartition *partition,
|
||||
const char *parameters)
|
||||
{
|
||||
return (partition && partition->ParentDiskSystem() == this
|
||||
&& fModule && fModule->validate_set_parameters
|
||||
&& fModule->validate_set_parameters(partition->PartitionData(),
|
||||
parameters));
|
||||
}
|
||||
|
||||
|
||||
// ValidateSetContentParameters
|
||||
//! Validates parameters for setting parameters of the content of a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateSetContentParameters(KPartition *partition,
|
||||
const char *parameters)
|
||||
{
|
||||
return (partition && partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_set_content_parameters
|
||||
&& fModule->validate_set_content_parameters(
|
||||
partition->PartitionData(), parameters));
|
||||
}
|
||||
|
||||
|
||||
// ValidateInitialize
|
||||
//! Validates parameters for initializing a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateInitialize(KPartition *partition, char *name,
|
||||
const char *parameters)
|
||||
{
|
||||
return (partition && fModule && fModule->validate_initialize
|
||||
&& fModule->validate_initialize(partition->PartitionData(), name,
|
||||
parameters));
|
||||
}
|
||||
|
||||
|
||||
// ValidateCreateChild
|
||||
//! Validates parameters for creating child of a partition
|
||||
bool
|
||||
KPartitioningSystem::ValidateCreateChild(KPartition *partition, off_t *start,
|
||||
off_t *size, const char *type, const char *parameters, int32 *index)
|
||||
{
|
||||
int32 _index = 0;
|
||||
if (!index)
|
||||
index = &_index;
|
||||
return (partition && start && size && type
|
||||
&& partition->DiskSystem() == this && fModule
|
||||
&& fModule->validate_create_child
|
||||
&& fModule->validate_create_child(partition->PartitionData(), start,
|
||||
size, type, parameters, index));
|
||||
}
|
||||
|
||||
|
||||
// CountPartitionableSpaces
|
||||
//! 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
|
||||
//! Retrieves a list of partitionable spaces on a partition
|
||||
status_t
|
||||
KPartitioningSystem::GetPartitionableSpaces(KPartition *partition,
|
||||
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(),
|
||||
buffer, count, actualCount);
|
||||
}
|
||||
|
||||
|
||||
// GetNextSupportedType
|
||||
//! Iterates through supported partition types
|
||||
status_t
|
||||
KPartitioningSystem::GetNextSupportedType(KPartition *partition, int32 *cookie,
|
||||
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
|
||||
//! 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
|
||||
//! Calls for additional modifications when shadow partition is changed
|
||||
status_t
|
||||
KPartitioningSystem::ShadowPartitionChanged(KPartition *partition,
|
||||
KPartition *child, 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(),
|
||||
child ? child->PartitionData() : NULL, operation);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
// Repair
|
||||
//! Repairs a partition
|
||||
@@ -877,6 +583,8 @@ KPartitioningSystem::DeleteChild(KPartition *child, KDiskDeviceJob *job)
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
#endif // 0
|
||||
|
||||
|
||||
// LoadModule
|
||||
status_t
|
||||
|
||||
@@ -182,6 +182,7 @@ KPhysicalPartition::CreateShadowPartition()
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// notify the disk systems
|
||||
// parent disk system
|
||||
status_t error;
|
||||
@@ -204,6 +205,7 @@ KPhysicalPartition::CreateShadowPartition()
|
||||
return error;
|
||||
}
|
||||
}
|
||||
#endif // 0
|
||||
}
|
||||
|
||||
// create shadows for children
|
||||
|
||||
@@ -1,492 +0,0 @@
|
||||
// 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 supports = (diskSystem
|
||||
&& diskSystem->SupportsOperations(partition,
|
||||
B_DISK_SYSTEM_SUPPORTS_MOVING));
|
||||
if (supports) {
|
||||
unmovable[0] = partition->ID();
|
||||
unmovableSize--;
|
||||
}
|
||||
if (supports && 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->SupportsOperations(partition,
|
||||
B_DISK_SYSTEM_SUPPORTS_MOVING));
|
||||
|
||||
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;
|
||||
|
||||
uint32 operations = diskSystem->GetSupportedOperations(partition,
|
||||
B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING
|
||||
| B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING_WHILE_MOUNTED);
|
||||
if (!(operations & B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING))
|
||||
return B_ERROR;
|
||||
|
||||
if (whileMounted) {
|
||||
*whileMounted = (operations
|
||||
& B_DISK_SYSTEM_SUPPORTS_DEFRAGMENTING_WHILE_MOUNTED);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
uint32 operations = diskSystem->GetSupportedOperations(partition,
|
||||
B_DISK_SYSTEM_SUPPORTS_REPAIRING
|
||||
| B_DISK_SYSTEM_SUPPORTS_REPAIRING_WHILE_MOUNTED);
|
||||
if (!(operations & B_DISK_SYSTEM_SUPPORTS_REPAIRING))
|
||||
return B_ERROR;
|
||||
|
||||
if (whileMounted) {
|
||||
*whileMounted = (operations
|
||||
& B_DISK_SYSTEM_SUPPORTS_REPAIRING_WHILE_MOUNTED);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// 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)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// truncate name to maximal size
|
||||
if (name)
|
||||
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
|
||||
int32 index;
|
||||
if (diskSystem->ValidateCreateChild(partition, offset, size, type,
|
||||
parameters, &index)) {
|
||||
if (_index)
|
||||
*_index = 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->SupportsChildOperations(partition,
|
||||
B_DISK_SYSTEM_SUPPORTS_DELETING_CHILD)) {
|
||||
return B_OK;
|
||||
}
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
//} // namespace DiskDevice
|
||||
//} // namespace BPrivate
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
// 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
|
||||
@@ -8,8 +8,6 @@
|
||||
#include <AutoDeleter.h>
|
||||
#include <ddm_userland_interface.h>
|
||||
#include <KDiskDevice.h>
|
||||
#include <KDiskDeviceJob.h>
|
||||
#include <KDiskDeviceJobQueue.h>
|
||||
#include <KDiskDeviceManager.h>
|
||||
#include <KDiskDeviceUtils.h>
|
||||
#include <KDiskSystem.h>
|
||||
@@ -17,8 +15,6 @@
|
||||
#include <KShadowPartition.h>
|
||||
#include <syscall_args.h>
|
||||
|
||||
#include "ddm_operation_validation.h"
|
||||
#include "KDiskDeviceJobGenerator.h"
|
||||
#include "UserDataWriter.h"
|
||||
|
||||
using namespace BPrivate::DiskDevice;
|
||||
@@ -51,6 +47,7 @@ ddm_strlcpy(char *to, const char *from, size_t size,
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// move_descendants
|
||||
static void
|
||||
move_descendants(KPartition *partition, off_t moveBy)
|
||||
@@ -86,6 +83,7 @@ move_descendants_contents(KPartition *partition)
|
||||
}
|
||||
return B_OK;
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
|
||||
// _user_get_next_disk_device_id
|
||||
@@ -283,67 +281,6 @@ _user_get_disk_device_data(partition_id id, bool deviceOnly, bool shadow,
|
||||
}
|
||||
|
||||
|
||||
// _user_get_partitionable_spaces
|
||||
status_t
|
||||
_user_get_partitionable_spaces(partition_id partitionID, int32 changeCounter,
|
||||
partitionable_space_data *_buffer, int32 count, int32 *_actualCount)
|
||||
{
|
||||
if (count > 0 && !_buffer)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (count > 0 && !IS_USER_ADDRESS(_buffer)
|
||||
|| _actualCount && !IS_USER_ADDRESS(_actualCount)) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
|
||||
// allocate buffer
|
||||
int32 bufferSize = count * sizeof(partitionable_space_data);
|
||||
partitionable_space_data *buffer = NULL;
|
||||
MemoryDeleter bufferDeleter;
|
||||
if (count > 0) {
|
||||
buffer = (partitionable_space_data*)malloc(bufferSize);
|
||||
if (!buffer)
|
||||
return B_NO_MEMORY;
|
||||
bufferDeleter.SetTo(buffer);
|
||||
}
|
||||
|
||||
status_t error = B_OK;
|
||||
|
||||
// get the partition
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
KPartition *partition = manager->ReadLockPartition(partitionID);
|
||||
if (!partition)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
PartitionRegistrar registrar1(partition, true);
|
||||
PartitionRegistrar registrar2(partition->Device(), true);
|
||||
DeviceReadLocker locker(partition->Device(), true);
|
||||
|
||||
if (!check_shadow_partition(partition, changeCounter))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
// get the disk system
|
||||
KDiskSystem *diskSystem = partition->DiskSystem();
|
||||
if (!diskSystem)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
// get the info
|
||||
int32 actualCount;
|
||||
error = diskSystem->GetPartitionableSpaces(partition, buffer, count,
|
||||
&actualCount);
|
||||
|
||||
// copy out
|
||||
if (_actualCount)
|
||||
user_memcpy(_actualCount, &actualCount, sizeof(actualCount));
|
||||
// copy even on error
|
||||
|
||||
if (error == B_OK && buffer)
|
||||
user_memcpy(_buffer, buffer, bufferSize);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// _user_register_file_device
|
||||
partition_id
|
||||
_user_register_file_device(const char *_filename)
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "disk_device_manager.h"
|
||||
#include "KDiskDevice.h"
|
||||
#include "KDiskDeviceJob.h"
|
||||
#include "KDiskDeviceJobQueue.h"
|
||||
#include "KDiskDeviceManager.h"
|
||||
#include "KDiskDeviceUtils.h"
|
||||
#include "KDiskSystem.h"
|
||||
@@ -232,7 +230,7 @@ scan_partition(partition_id partitionID)
|
||||
PartitionRegistrar _(partition, true);
|
||||
|
||||
// scan it
|
||||
return manager->ScanPartition(partition, false);
|
||||
return manager->ScanPartition(partition);
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +251,7 @@ find_disk_system(const char *name)
|
||||
bool
|
||||
update_disk_device_job_progress(disk_job_id jobID, float progress)
|
||||
{
|
||||
#if 0
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
if (KDiskDeviceJob *job = manager->FindJob(jobID)) {
|
||||
@@ -260,6 +259,7 @@ update_disk_device_job_progress(disk_job_id jobID, float progress)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -268,6 +268,7 @@ update_disk_device_job_progress(disk_job_id jobID, float progress)
|
||||
bool
|
||||
update_disk_device_job_extra_progress(disk_job_id jobID, const char *info)
|
||||
{
|
||||
#if 0
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
if (KDiskDeviceJob *job = manager->FindJob(jobID)) {
|
||||
@@ -275,6 +276,7 @@ update_disk_device_job_extra_progress(disk_job_id jobID, const char *info)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -283,6 +285,7 @@ update_disk_device_job_extra_progress(disk_job_id jobID, const char *info)
|
||||
bool
|
||||
set_disk_device_job_error_message(disk_job_id jobID, const char *message)
|
||||
{
|
||||
#if 0
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (ManagerLocker locker = manager) {
|
||||
if (KDiskDeviceJob *job = manager->FindJob(jobID)) {
|
||||
@@ -290,6 +293,7 @@ set_disk_device_job_error_message(disk_job_id jobID, const char *message)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -299,6 +303,7 @@ uint32
|
||||
update_disk_device_job_interrupt_properties(disk_job_id jobID,
|
||||
uint32 interruptProperties)
|
||||
{
|
||||
#if 0
|
||||
bool paused = false;
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
do {
|
||||
@@ -329,6 +334,7 @@ update_disk_device_job_interrupt_properties(disk_job_id jobID,
|
||||
pauseSemaphore = -1;
|
||||
}
|
||||
} while (paused);
|
||||
#endif
|
||||
return B_DISK_DEVICE_JOB_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/**
|
||||
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::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 : strdup(type)),
|
||||
fParameters(!parameters ? NULL : strdup(parameters))
|
||||
{
|
||||
SetDescription( "creating child of the partition" );
|
||||
}
|
||||
|
||||
|
||||
KCreateChildJob::~KCreateChildJob()
|
||||
{
|
||||
free(fType);
|
||||
free(fParameters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 validationResult = validate_create_child_partition(
|
||||
partition, partition->ChangeCounter(),
|
||||
&newOffset, &fSize, fType,
|
||||
fParameters, NULL, false);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validating of creating new child failed!");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
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 createResult = diskSystem->CreateChild(partition, newOffset,
|
||||
newSize, fType, fParameters, this, &newChild, fChildID);
|
||||
|
||||
if (createResult != B_OK) {
|
||||
SetErrorMessage("Creating new partition child failed!");
|
||||
return createResult;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
else {
|
||||
SetErrorMessage("Couldn't find partition.");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_CREATE_CHILD_JOB_H
|
||||
#define _K_DISK_DEVICE_CREATE_CHILD_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Create new child of given partition
|
||||
*/
|
||||
class KCreateChildJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KCreateChildJob(partition_id partition, partition_id child, off_t offset,
|
||||
off_t size, const char *type, const char *parameters);
|
||||
virtual ~KCreateChildJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
partition_id fChildID;
|
||||
off_t fOffset;
|
||||
off_t fSize;
|
||||
char* fType;
|
||||
char* fParameters;
|
||||
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KCreateChildJob;
|
||||
|
||||
#endif // _DISK_DEVICE_CREATE_CHILD_JOB_H
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/**
|
||||
Creates the job
|
||||
|
||||
\param partition which device should we defragment
|
||||
*/
|
||||
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 validationResult = validate_defragment_partition(
|
||||
partition, partition->ChangeCounter(), &whileMounted, false);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation of defragmenting partition failed.");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
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 defragResult = diskSystem->Defragment(partition, this);
|
||||
|
||||
if (defragResult != B_OK) {
|
||||
SetErrorMessage("Defragmenting partition failed!");
|
||||
return defragResult;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition!");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_DEFRAGMENT_JOB_H
|
||||
#define _K_DISK_DEVICE_DEFRAGMENT_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Defragments the device
|
||||
*/
|
||||
class KDefragmentJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KDefragmentJob(partition_id partition);
|
||||
virtual ~KDefragmentJob();
|
||||
|
||||
virtual status_t Do();
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KDefragmentJob;
|
||||
|
||||
#endif // _DISK_DEVICE_DEFRAGMENT_JOB_H
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/*!
|
||||
Creates the job
|
||||
|
||||
\param parent device of the deleted partition
|
||||
\param partition partition supposed to be removed
|
||||
*/
|
||||
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 validationResult = validate_delete_child_partition(
|
||||
partition, partition->ChangeCounter(), false);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation of deleting child failed!");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
// everything OK, let's do the job!
|
||||
KDiskSystem *parentDiskSystem = partition->ParentDiskSystem();
|
||||
DiskSystemLoader loader(parentDiskSystem );
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
status_t deleteResult = parentDiskSystem->DeleteChild(partition, this);
|
||||
|
||||
if (deleteResult != B_OK) {
|
||||
SetErrorMessage("Deleting child failed!");
|
||||
return deleteResult;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition!");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_DELETE_CHILD_JOB_H
|
||||
#define _K_DISK_DEVICE_DELETE_CHILD_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Deletes specific child of a partition/device
|
||||
*/
|
||||
class KDeleteChildJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KDeleteChildJob(partition_id parent, partition_id partition);
|
||||
virtual ~KDeleteChildJob();
|
||||
|
||||
virtual status_t Do();
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KDeleteChildJob;
|
||||
|
||||
#endif // _DISK_DEVICE_DELETE_CHILD_JOB_H
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.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
|
||||
|
||||
|
||||
/*!
|
||||
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::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 : strdup(name)),
|
||||
fParameters(!parameters ? NULL : strdup(parameters))
|
||||
{
|
||||
SetDescription("initializing the partition with given disk system");
|
||||
}
|
||||
|
||||
|
||||
KInitializeJob::~KInitializeJob()
|
||||
{
|
||||
free(fName);
|
||||
free(fParameters);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KInitializeJob::Do()
|
||||
{
|
||||
DBG(OUT("KInitializeJob::Do(%ld)\n", PartitionID()));
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
KPartition *partition = manager->WriteLockPartition(PartitionID());
|
||||
if (!partition) {
|
||||
SetErrorMessage("Couldn't find partition.");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
PartitionRegistrar registrar(partition, true);
|
||||
PartitionRegistrar deviceRegistrar(partition->Device(), true);
|
||||
|
||||
DeviceWriteLocker locker(partition->Device(), true);
|
||||
|
||||
// basic checks
|
||||
|
||||
// all descendants should be marked busy/descendant busy
|
||||
if (IsPartitionNotBusy(partition)) {
|
||||
SetErrorMessage("Can't initialize non-busy partition!");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (partition->DiskSystem()) {
|
||||
SetErrorMessage("Partition is already initialized.");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// get the disk system
|
||||
KDiskSystem *diskSystemToInit = manager->LoadDiskSystem(fDiskSystemID);
|
||||
if (!diskSystemToInit) {
|
||||
SetErrorMessage("Given DiskSystemID doesn't correspond to any "
|
||||
"known DiskSystem.");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
DiskSystemLoader loader(diskSystemToInit, true);
|
||||
|
||||
// check the parameters
|
||||
char name[B_DISK_DEVICE_NAME_LENGTH];
|
||||
if (fName)
|
||||
strlcpy(name, fName, sizeof(name));
|
||||
|
||||
status_t error = validate_initialize_partition(partition,
|
||||
partition->ChangeCounter(), diskSystemToInit->Name(),
|
||||
fName ? name : NULL, fParameters, false);
|
||||
|
||||
if (error != B_OK) {
|
||||
SetErrorMessage("Validation of initializing partition failed.");
|
||||
return error;
|
||||
}
|
||||
|
||||
if (fName != NULL && strcmp(fName, name) != 0) {
|
||||
SetErrorMessage("Requested name not valid.");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// everything seems OK -> let's do the job
|
||||
locker.Unlock();
|
||||
|
||||
error = diskSystemToInit->Initialize(partition, fName, fParameters, this);
|
||||
if (error != B_OK) {
|
||||
SetErrorMessage("Initialization of partition failed!");
|
||||
return error;
|
||||
}
|
||||
|
||||
locker.Lock();
|
||||
|
||||
if (partition->DiskSystem()) {
|
||||
// The disk system might have triggered a rescan after initializing, in
|
||||
// which case the disk system is already set. Just check, if it is the
|
||||
// right one.
|
||||
if (partition->DiskSystem() != diskSystemToInit) {
|
||||
SetErrorMessage("Partition has wrong disk system after "
|
||||
"initialization.");
|
||||
return B_ERROR;
|
||||
}
|
||||
} else
|
||||
partition->SetDiskSystem(diskSystemToInit);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_INITIALIZE_JOB_H
|
||||
#define _K_DISK_DEVICE_INITIALIZE_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Initializes the device with given disk system (i.e. partitioning or file system)
|
||||
*/
|
||||
class KInitializeJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KInitializeJob(partition_id partition, disk_system_id diskSystemID,
|
||||
const char *name, const char *parameters);
|
||||
virtual ~KInitializeJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
disk_system_id fDiskSystemID;
|
||||
char * fName;
|
||||
char * fParameters;
|
||||
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KInitializeJob;
|
||||
|
||||
#endif // _DISK_DEVICE_INITIALIZE_JOB_H
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/**
|
||||
Creates the job.
|
||||
|
||||
\param parentID the device whose child should be moved
|
||||
\param partitionID the child to move
|
||||
\param offset where to move
|
||||
*/
|
||||
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 newOffset = fNewOffset;
|
||||
|
||||
status_t validateResult = validate_move_partition(partition,
|
||||
partition->ChangeCounter(), &newOffset, true, false);
|
||||
// TODO posledni 2 parametry????
|
||||
// TODO: Huh?
|
||||
if (validateResult != B_OK) {
|
||||
SetErrorMessage("Validation of the new partition offset failed.");
|
||||
return validateResult;
|
||||
}
|
||||
|
||||
if (newOffset != 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 moveResult = parentDiskSystem->Move(partition, fNewOffset,
|
||||
this);
|
||||
if (moveResult != B_OK) {
|
||||
SetErrorMessage("Moving of partition failed.");
|
||||
}
|
||||
return moveResult;
|
||||
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition.");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_MOVE_JOB_H
|
||||
#define _K_DISK_DEVICE_MOVE_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Moves given child of a partition/device
|
||||
*/
|
||||
class KMoveJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KMoveJob(partition_id parentID, partition_id partitionID, off_t offset);
|
||||
virtual ~KMoveJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
off_t fNewOffset;
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KMoveJob;
|
||||
|
||||
#endif // _DISK_DEVICE_MOVE_JOB_H
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/**
|
||||
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::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 validationResult = validate_repair_partition(partition,
|
||||
partition->ChangeCounter(), fCheckOnly, &whileMounted, false);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation repairing partition failed!");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
// everything OK, let's do the job
|
||||
KDiskSystem* diskSystem = partition->DiskSystem();
|
||||
DiskSystemLoader loader(diskSystem);
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
status_t repairResult = diskSystem->Repair(partition, fCheckOnly, this);
|
||||
|
||||
if (repairResult != B_OK) {
|
||||
if (fCheckOnly) {
|
||||
SetErrorMessage("Checking for repairing partition failed!");
|
||||
} else {
|
||||
SetErrorMessage("Repairing partition failed!");
|
||||
}
|
||||
return repairResult;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition!");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_REPAIR_JOB_H
|
||||
#define _K_DISK_DEVICE_REPAIR_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Repair partition (or check for repairs)
|
||||
*/
|
||||
class KRepairJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KRepairJob(partition_id partition, bool checkOnly);
|
||||
virtual ~KRepairJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
bool fCheckOnly;
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KRepairJob;
|
||||
|
||||
#endif // _DISK_DEVICE_REPAIR_JOB_H
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
|
||||
#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"
|
||||
#include "KResizeJob.h"
|
||||
|
||||
|
||||
// debugging
|
||||
//#define DBG(x)
|
||||
#define DBG(x) x
|
||||
#define OUT dprintf
|
||||
|
||||
|
||||
// constructor
|
||||
/**
|
||||
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::KResizeJob(partition_id parentID, partition_id partitionID,
|
||||
off_t size)
|
||||
: KDiskDeviceJob(B_DISK_DEVICE_JOB_RESIZE, partitionID, parentID),
|
||||
fSize(size)
|
||||
{
|
||||
SetDescription("resizing partition");
|
||||
}
|
||||
|
||||
|
||||
// destructor
|
||||
KResizeJob::~KResizeJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Do
|
||||
status_t
|
||||
KResizeJob::Do()
|
||||
{
|
||||
DBG(OUT("KResizeJob::Do(%ld)\n", PartitionID()));
|
||||
|
||||
// get the partition
|
||||
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;
|
||||
}
|
||||
|
||||
// if size remains the same, then nothing's to do
|
||||
if (partition->Size() == fSize)
|
||||
return B_OK;
|
||||
|
||||
// check new size
|
||||
off_t size = fSize;
|
||||
off_t contentSize = fSize;
|
||||
status_t error = validate_resize_partition(partition,
|
||||
partition->ChangeCounter(), &size, &contentSize, false);
|
||||
if (error != B_OK) {
|
||||
SetErrorMessage("Validation of the new partition size failed.");
|
||||
return error;
|
||||
}
|
||||
if (size != fSize) {
|
||||
SetErrorMessage("Requested size is not valid.");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// all descendants should be marked busy/descendant busy
|
||||
struct IsNotBusyVisitor : KPartitionVisitor {
|
||||
virtual bool VisitPre(KPartition *partition)
|
||||
{
|
||||
return !(partition->IsBusy() || partition->IsDescendantBusy());
|
||||
}
|
||||
} isNotBusyVisitor;
|
||||
if (partition->VisitEachDescendant(&isNotBusyVisitor)) {
|
||||
SetErrorMessage("Can't resize non-busy partition!");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// things look good: get all infos needed for resizing
|
||||
KDiskSystem *parentDiskSystem = partition->ParentDiskSystem();
|
||||
KDiskSystem *childDiskSystem = partition->DiskSystem();
|
||||
DiskSystemLoader loader1(parentDiskSystem);
|
||||
DiskSystemLoader loader2(childDiskSystem);
|
||||
off_t oldSize = partition->Size();
|
||||
off_t oldContentSize = partition->ContentSize();
|
||||
|
||||
// unlock the device and resize the beast
|
||||
locker.Unset();
|
||||
|
||||
// if growing, resize partition first
|
||||
if (oldSize < fSize) {
|
||||
status_t error = parentDiskSystem->ResizeChild(partition, fSize,
|
||||
this);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
// resize contents
|
||||
if (childDiskSystem && oldContentSize != contentSize) {
|
||||
status_t error = childDiskSystem->Resize(partition, contentSize,
|
||||
this);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
// if shrinking, resize partition last
|
||||
if (oldSize > fSize) {
|
||||
status_t error = parentDiskSystem->ResizeChild(partition, fSize,
|
||||
this);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition.");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_RESIZE_JOB_H
|
||||
#define _K_DISK_DEVICE_RESIZE_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Resizes a partition.
|
||||
*/
|
||||
class KResizeJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KResizeJob(partition_id parentID, partition_id partitionID, off_t size);
|
||||
virtual ~KResizeJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
off_t fSize;
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KResizeJob;
|
||||
|
||||
#endif // _DISK_DEVICE_RESIZE_JOB_H
|
||||
@@ -1,150 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "KDiskDevice.h"
|
||||
#include "KDiskDeviceManager.h"
|
||||
#include "KDiskDeviceUtils.h"
|
||||
#include "KDiskSystem.h"
|
||||
#include "KPartition.h"
|
||||
#include "KPath.h"
|
||||
#include "KScanPartitionJob.h"
|
||||
|
||||
// debugging
|
||||
#define DBG(x)
|
||||
#define OUT dprintf
|
||||
|
||||
|
||||
/**
|
||||
Creates the job.
|
||||
|
||||
\param partitionID the partition to scan
|
||||
*/
|
||||
KScanPartitionJob::KScanPartitionJob(partition_id partitionID)
|
||||
: KDiskDeviceJob(B_DISK_DEVICE_JOB_SCAN, partitionID)
|
||||
{
|
||||
SetDescription("scanning partition");
|
||||
}
|
||||
|
||||
|
||||
KScanPartitionJob::~KScanPartitionJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KScanPartitionJob::Do()
|
||||
{
|
||||
// get the partition
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
KPartition *partition = manager->WriteLockPartition(PartitionID());
|
||||
if (!partition)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
KDiskDevice *device = partition->Device();
|
||||
PartitionRegistrar registrar1(partition, true);
|
||||
PartitionRegistrar registrar2(device, true);
|
||||
DeviceWriteLocker locker(device, true);
|
||||
// scan the partition
|
||||
status_t error = B_OK;
|
||||
if (device->HasMedia()) {
|
||||
error = _ScanPartition(partition);
|
||||
if (error != B_OK) {
|
||||
// ...
|
||||
error = B_OK;
|
||||
}
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KScanPartitionJob::_ScanPartition(KPartition *partition)
|
||||
{
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
// the partition's device must be write-locked
|
||||
if (!partition)
|
||||
return B_BAD_VALUE;
|
||||
if (partition->DiskSystem() != NULL) {
|
||||
// TODO: this is more or less a hack to prevent rescanning a partition
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++)
|
||||
_ScanPartition(child);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
DBG(
|
||||
KPath partitionPath;
|
||||
partition->GetPath(&partitionPath);
|
||||
OUT("KDiskDeviceManager::_ScanPartition(%s)\n", partitionPath.Path());
|
||||
)
|
||||
|
||||
// publish the partition
|
||||
status_t error = B_OK;
|
||||
if (!partition->IsPublished()) {
|
||||
error = partition->PublishDevice();
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
}
|
||||
|
||||
// find the disk system that returns the best priority for this partition
|
||||
float bestPriority = -1;
|
||||
KDiskSystem *bestDiskSystem = NULL;
|
||||
void *bestCookie = NULL;
|
||||
int32 itCookie = 0;
|
||||
while (KDiskSystem *diskSystem = manager->LoadNextDiskSystem(&itCookie)) {
|
||||
DBG(OUT(" trying: %s\n", diskSystem->Name()));
|
||||
|
||||
void *cookie = NULL;
|
||||
float priority = diskSystem->Identify(partition, &cookie);
|
||||
|
||||
DBG(OUT(" returned: %ld/1000\n", int32(1000 * priority)));
|
||||
|
||||
if (priority >= 0 && priority > bestPriority) {
|
||||
// new best disk system
|
||||
if (bestDiskSystem) {
|
||||
bestDiskSystem->FreeIdentifyCookie(partition, bestCookie);
|
||||
bestDiskSystem->Unload();
|
||||
}
|
||||
bestPriority = priority;
|
||||
bestDiskSystem = diskSystem;
|
||||
bestCookie = cookie;
|
||||
} else {
|
||||
// disk system doesn't identify the partition or worse than our
|
||||
// current favorite
|
||||
if (priority >= 0)
|
||||
diskSystem->FreeIdentifyCookie(partition, cookie);
|
||||
diskSystem->Unload();
|
||||
}
|
||||
}
|
||||
|
||||
// now, if we have found a disk system, let it scan the partition
|
||||
if (bestDiskSystem) {
|
||||
DBG(OUT(" scanning with: %s\n", bestDiskSystem->Name()));
|
||||
error = bestDiskSystem->Scan(partition, bestCookie);
|
||||
bestDiskSystem->FreeIdentifyCookie(partition, bestCookie);
|
||||
if (error == B_OK) {
|
||||
partition->SetDiskSystem(bestDiskSystem);
|
||||
for (int32 i = 0; KPartition *child = partition->ChildAt(i); i++)
|
||||
_ScanPartition(child);
|
||||
} else {
|
||||
// TODO: Handle the error.
|
||||
DBG(OUT(" scanning failed: %s\n", strerror(error)));
|
||||
}
|
||||
// now we can safely unload the disk system -- it has been loaded by
|
||||
// the partition(s) and thus will not really be unloaded
|
||||
bestDiskSystem->Unload();
|
||||
} else {
|
||||
// contents not recognized
|
||||
// nothing to be done -- partitions are created as unrecognized
|
||||
}
|
||||
return error;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_SCAN_PARTITION_JOB_H
|
||||
#define _K_DISK_DEVICE_SCAN_PARTITION_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
class KPartition;
|
||||
|
||||
/**
|
||||
* Scans partition and tries to find the most suitable disk system for it
|
||||
*/
|
||||
class KScanPartitionJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KScanPartitionJob(partition_id partitionID);
|
||||
virtual ~KScanPartitionJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
status_t _ScanPartition(KPartition *partition);
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KScanPartitionJob;
|
||||
|
||||
#endif // _DISK_DEVICE_SCAN_PARTITION_JOB_H
|
||||
@@ -1,148 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Lubos Kulic <[email protected]>
|
||||
*/
|
||||
|
||||
#include "KSetNameJob.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"
|
||||
|
||||
|
||||
/**
|
||||
Creates the job.
|
||||
|
||||
\param partitionID the partition/device whose name should be set
|
||||
\param name the new name for \c partitionID
|
||||
\param contentName the new name for the content of \c partitionID
|
||||
*/
|
||||
KSetNameJob::KSetNameJob(partition_id parentID, partition_id partitionID,
|
||||
const char* name, const char* contentName)
|
||||
: KDiskDeviceJob(B_DISK_DEVICE_JOB_SET_NAME, partitionID, parentID),
|
||||
fName(!name ? NULL : strdup(name)),
|
||||
fContentName(!contentName ? NULL : strdup(contentName))
|
||||
{
|
||||
SetDescription("setting name for the partition or its content");
|
||||
}
|
||||
|
||||
|
||||
KSetNameJob::~KSetNameJob()
|
||||
{
|
||||
free(fName);
|
||||
free(fContentName);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KSetNameJob::Do()
|
||||
{
|
||||
KDiskDeviceManager* manager = KDiskDeviceManager::Default();
|
||||
|
||||
KPartition* partition = manager->WriteLockPartition(PartitionID());
|
||||
if (partition) {
|
||||
if (!fName && !fContentName) {
|
||||
SetErrorMessage("No name to set.");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
PartitionRegistrar registrar(partition, true);
|
||||
PartitionRegistrar deviceRegistrar(partition->Device(), true);
|
||||
|
||||
// TODO is lock necessary?
|
||||
DeviceWriteLocker locker(partition->Device(), true);
|
||||
|
||||
// basic checks
|
||||
|
||||
// all descendants should be marked busy/descendant busy
|
||||
if (IsPartitionNotBusy(partition)) {
|
||||
SetErrorMessage("Can't set name for non-busy partition!");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
if (fName) {
|
||||
// set name of the partition
|
||||
|
||||
// setting name of this partition -> via our parent disk system
|
||||
if (!partition->ParentDiskSystem()) {
|
||||
SetErrorMessage("Partition has no parent disk system!");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// TODO maybe give copy of name
|
||||
// TODO: The parameters are already validated and should not be changed again!
|
||||
status_t validationResult = validate_set_partition_name(
|
||||
partition, partition->ChangeCounter(), fName, false);
|
||||
|
||||
if( validationResult != B_OK) {
|
||||
SetErrorMessage( "Validation of setting partition name failed!" );
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
// everything OK, let's do the job
|
||||
KDiskSystem* parentDiskSystem = partition->ParentDiskSystem();
|
||||
|
||||
DiskSystemLoader loader(parentDiskSystem);
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
status_t setNameResult = parentDiskSystem->SetName(partition, fName,
|
||||
this);
|
||||
if (setNameResult != B_OK) {
|
||||
SetErrorMessage( "Setting name of the partition failed!" );
|
||||
}
|
||||
return setNameResult;
|
||||
}
|
||||
|
||||
if (fContentName) {
|
||||
// set name of the contents
|
||||
|
||||
// setting name of our contents -> via our disk system
|
||||
if (!partition->DiskSystem()) {
|
||||
SetErrorMessage( "Partition has no disk system!");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// TODO: The parameters are already validated and should not be changed again!
|
||||
status_t validationResult = validate_set_partition_content_name(
|
||||
partition, partition->ChangeCounter(), fContentName, false);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation of setting partition content name "
|
||||
"failed!");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
// everything OK, let's do the job
|
||||
|
||||
KDiskSystem* diskSystem = partition->DiskSystem();
|
||||
DiskSystemLoader loader(diskSystem);
|
||||
|
||||
locker.Unlock();
|
||||
|
||||
status_t result = diskSystem->SetContentName(partition,
|
||||
fContentName, this);
|
||||
if (result != B_OK) {
|
||||
SetErrorMessage("Setting name of the partition's content "
|
||||
"failed!" );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition!");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
return B_ERROR;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Lubos Kulic <[email protected]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_SET_NAME_JOB_H
|
||||
#define _K_DISK_DEVICE_SET_NAME_JOB_H
|
||||
|
||||
#include <KDiskDeviceJob.h>
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Sets the name for partition/device and/or its content
|
||||
*
|
||||
* - can set both name and content name for the partition - but
|
||||
* it's possible to create it with only one of these name parameters and so
|
||||
* set only one of the names
|
||||
*/
|
||||
class KSetNameJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KSetNameJob(partition_id parentID, partition_id partitionID,
|
||||
const char* name, const char* contentName);
|
||||
virtual ~KSetNameJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
char* fName;
|
||||
char* fContentName;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using BPrivate::DiskDevice::KSetNameJob;
|
||||
|
||||
#endif
|
||||
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
|
||||
/**
|
||||
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::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 : strdup(parameters)),
|
||||
fContentParams(!contentParameters ? NULL : strdup(contentParameters))
|
||||
{
|
||||
SetDescription("setting partition parameters&content parameters");
|
||||
}
|
||||
|
||||
|
||||
KSetParametersJob::~KSetParametersJob()
|
||||
{
|
||||
free(fParams);
|
||||
free(fContentParams);
|
||||
}
|
||||
|
||||
|
||||
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 maybe give copy of parameters?
|
||||
// we have some parameters to set
|
||||
// TODO: The parameters are already validated and should not be changed again!
|
||||
status_t validationResult = validate_set_partition_parameters(
|
||||
partition, partition->ChangeCounter(), fParams, false);
|
||||
|
||||
KDiskSystem *parentDiskSystem = partition->ParentDiskSystem();
|
||||
DiskSystemLoader loader(parentDiskSystem);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation of setting partition parameters "
|
||||
"failed.");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
locker.Unlock();
|
||||
status_t setParametersResult = parentDiskSystem->SetParameters(
|
||||
partition, fParams, this);
|
||||
|
||||
if (setParametersResult != B_OK) {
|
||||
SetErrorMessage( "Setting partition parameters failed." );
|
||||
}
|
||||
}
|
||||
|
||||
if (fContentParams) {
|
||||
// basic checks
|
||||
|
||||
if (!partition->DiskSystem()) {
|
||||
SetErrorMessage("Partition has no disk system!");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// TODO: The parameters are already validated and should not be changed again!
|
||||
status_t validationResult
|
||||
= validate_set_partition_content_parameters(partition,
|
||||
partition->ChangeCounter(), fContentParams, false);
|
||||
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation of setting partition content "
|
||||
"parameters failed.");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
KDiskSystem *diskSystem = partition->DiskSystem();
|
||||
DiskSystemLoader loader(diskSystem);
|
||||
|
||||
locker.Unlock();
|
||||
status_t result = diskSystem->SetContentParameters(partition,
|
||||
fContentParams, this);
|
||||
|
||||
if (result != B_OK) {
|
||||
SetErrorMessage("Setting partition content parameters failed.");
|
||||
}
|
||||
}
|
||||
// TODO: Check return values!
|
||||
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
SetErrorMessage( "Couldn't find partition" );
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_SET_PARAMETERS_JOB_H
|
||||
#define _K_DISK_DEVICE_SET_PARAMETERS_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
|
||||
/**
|
||||
* 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:
|
||||
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
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KSetParametersJob;
|
||||
|
||||
#endif // _DISK_DEVICE_SET_PARAMETERS_JOB_H
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Lubos Kulic <[email protected]>
|
||||
*/
|
||||
|
||||
#include <KPartition.h>
|
||||
#include <KernelExport.h>
|
||||
#include <DiskDeviceDefs.h>
|
||||
#include <KDiskDevice.h>
|
||||
#include <KDiskDeviceManager.h>
|
||||
#include <KDiskDeviceUtils.h>
|
||||
#include <KDiskSystem.h>
|
||||
|
||||
#include <KPartitionVisitor.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "KSetTypeJob.h"
|
||||
#include "ddm_operation_validation.h"
|
||||
|
||||
|
||||
/**
|
||||
Creates the job.
|
||||
|
||||
\param partitionID the partition whose type should be set
|
||||
\param type the new type for the partition
|
||||
*/
|
||||
KSetTypeJob::KSetTypeJob(partition_id parentID, partition_id partitionID,
|
||||
const char *type)
|
||||
: KDiskDeviceJob(B_DISK_DEVICE_JOB_SET_TYPE, partitionID, parentID),
|
||||
fType(!type ? NULL : strdup(type))
|
||||
{
|
||||
SetDescription("setting partition type");
|
||||
}
|
||||
|
||||
|
||||
KSetTypeJob::~KSetTypeJob()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
KSetTypeJob::Do()
|
||||
{
|
||||
KDiskDeviceManager* manager = KDiskDeviceManager::Default();
|
||||
|
||||
KPartition* partition = manager->WriteLockPartition(PartitionID());
|
||||
|
||||
if (partition) {
|
||||
PartitionRegistrar registrar(partition, true);
|
||||
PartitionRegistrar deviceRegistrar(partition->Device(), true);
|
||||
|
||||
// TODO is lock necessary?
|
||||
DeviceWriteLocker locker(partition->Device(), true);
|
||||
|
||||
// basic checks
|
||||
if (!partition->ParentDiskSystem()) {
|
||||
SetErrorMessage("Partition has no parent disk system!");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
if (!fType) {
|
||||
SetErrorMessage("No type to set!");
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
// TODO: The parameters are already validated and should not be changed again!
|
||||
status_t validationResult = validate_set_partition_type(
|
||||
partition, partition->ChangeCounter(), fType, false);
|
||||
if (validationResult != B_OK) {
|
||||
SetErrorMessage("Validation of setting partition type failed!");
|
||||
return validationResult;
|
||||
}
|
||||
|
||||
// everything OK, let's do the job
|
||||
KDiskSystem* parentDiskSystem = partition->ParentDiskSystem();
|
||||
DiskSystemLoader loader(parentDiskSystem);
|
||||
|
||||
status_t setTypeResult = parentDiskSystem->SetType(partition, fType,
|
||||
this);
|
||||
|
||||
if (setTypeResult != B_OK) {
|
||||
SetErrorMessage("Setting partition type failed!");
|
||||
return setTypeResult;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition!");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Lubos Kulic <[email protected]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_SET_TYPE_JOB_H
|
||||
#define _K_DISK_DEVICE_SET_TYPE_JOB_H
|
||||
|
||||
#include <KDiskDeviceJob.h>
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Sets type of the device/partition
|
||||
*/
|
||||
class KSetTypeJob : public KDiskDeviceJob
|
||||
{
|
||||
public:
|
||||
KSetTypeJob(partition_id parentID, partition_id partitionID, const char *type);
|
||||
virtual ~KSetTypeJob();
|
||||
|
||||
virtual status_t Do();
|
||||
|
||||
private:
|
||||
char * fType;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
using BPrivate::DiskDevice::KSetTypeJob;
|
||||
|
||||
#endif
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <KernelExport.h>
|
||||
#include <DiskDeviceDefs.h>
|
||||
#include <KDiskDevice.h>
|
||||
#include <KDiskDeviceManager.h>
|
||||
#include <KDiskDeviceUtils.h>
|
||||
#include <KPartition.h>
|
||||
#include <KPartitionVisitor.h>
|
||||
|
||||
#include "KUninitializeJob.h"
|
||||
|
||||
// debugging
|
||||
//#define DBG(x)
|
||||
#define DBG(x) x
|
||||
#define OUT dprintf
|
||||
|
||||
// constructor
|
||||
KUninitializeJob::KUninitializeJob(partition_id partitionID)
|
||||
: KDiskDeviceJob(B_DISK_DEVICE_JOB_UNINITIALIZE, partitionID)
|
||||
{
|
||||
SetDescription("uninitializing partition");
|
||||
}
|
||||
|
||||
// destructor
|
||||
KUninitializeJob::~KUninitializeJob()
|
||||
{
|
||||
}
|
||||
|
||||
// Do
|
||||
status_t
|
||||
KUninitializeJob::Do()
|
||||
{
|
||||
DBG(OUT("KUninitializeJob::Do(%ld)\n", PartitionID()));
|
||||
// get the partition
|
||||
KDiskDeviceManager *manager = KDiskDeviceManager::Default();
|
||||
if (KPartition *partition = manager->WriteLockPartition(PartitionID())) {
|
||||
PartitionRegistrar registrar1(partition, true);
|
||||
PartitionRegistrar registrar2(partition->Device(), true);
|
||||
DeviceWriteLocker locker(partition->Device(), true);
|
||||
// the partition's descendants must not be mounted
|
||||
struct IsMountedVisitor : KPartitionVisitor {
|
||||
virtual bool VisitPre(KPartition *partition)
|
||||
{
|
||||
return partition->IsMounted();
|
||||
}
|
||||
} isMountedVisitor;
|
||||
if (partition->VisitEachDescendant(&isMountedVisitor)) {
|
||||
SetErrorMessage("Can't uninitialize mounted partition.");
|
||||
return B_ERROR;
|
||||
}
|
||||
// all descendants should be marked busy/descendant busy
|
||||
struct IsNotBusyVisitor : KPartitionVisitor {
|
||||
virtual bool VisitPre(KPartition *partition)
|
||||
{
|
||||
return !(partition->IsBusy() || partition->IsDescendantBusy());
|
||||
}
|
||||
} isNotBusyVisitor;
|
||||
if (partition->VisitEachDescendant(&isNotBusyVisitor)) {
|
||||
SetErrorMessage("Can't uninitialize non-busy partition!");
|
||||
return B_ERROR;
|
||||
}
|
||||
// things look good: uninitialize the thing
|
||||
status_t error = partition->UninitializeContents();
|
||||
if (error != B_OK)
|
||||
SetErrorMessage("Failed to uninitialize partition contents!");
|
||||
return error;
|
||||
} else {
|
||||
SetErrorMessage("Couldn't find partition.");
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
// cannot come here
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2007, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Ingo Weinhold <[email protected]>
|
||||
*/
|
||||
#ifndef _K_DISK_DEVICE_UNINITIALIZE_JOB_H
|
||||
#define _K_DISK_DEVICE_UNINITIALIZE_JOB_H
|
||||
|
||||
#include "KDiskDeviceJob.h"
|
||||
|
||||
namespace BPrivate {
|
||||
namespace DiskDevice {
|
||||
|
||||
/**
|
||||
* Uninitializes the partition/device
|
||||
*/
|
||||
class KUninitializeJob : public KDiskDeviceJob {
|
||||
public:
|
||||
KUninitializeJob(partition_id partitionID);
|
||||
virtual ~KUninitializeJob();
|
||||
|
||||
virtual status_t Do();
|
||||
};
|
||||
|
||||
} // namespace DiskDevice
|
||||
} // namespace BPrivate
|
||||
|
||||
using BPrivate::DiskDevice::KUninitializeJob;
|
||||
|
||||
#endif // _K_DISK_DEVICE_UNINITIALIZE_JOB_H
|
||||
@@ -5350,7 +5350,7 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags,
|
||||
// an invalid path, or the path refers to an image file. We try
|
||||
// to let the DDM create a file device for the path.
|
||||
partition_id deviceID = ddm->CreateFileDevice(normalizedDevice.Path(),
|
||||
&newlyCreatedFileDevice, false);
|
||||
&newlyCreatedFileDevice);
|
||||
if (deviceID >= 0) {
|
||||
partition = ddm->RegisterPartition(deviceID, true);
|
||||
if (newlyCreatedFileDevice)
|
||||
|
||||
Reference in New Issue
Block a user