* Added base class of job classes DiskDeviceJob and job container class

DiskDeviceJobQueue.
* Basic synchronous implementation of BDiskDevice::CommitModifications(),
  ignoring the given parameters, though.
* Some more work on DiskDeviceJobGenerator: Added class
  PartitionReference which will reference a partition while the jobs are
  executed. The generator manages the mapping of partitions to those
  references now. Also exemplarily implemented the generation of the
  InitializeJob.
* Moved support functionality to private header DiskDeviceUtils.h.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22620 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2007-10-19 03:18:28 +00:00
parent 25d7f14a9c
commit c70623faaf
14 changed files with 516 additions and 50 deletions

View File

@ -12,6 +12,7 @@ UseArchHeaders $(TARGET_ARCH) ;
UsePublicHeaders [ FDirName add-ons registrar ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) disk_device ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) disk_device jobs ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) mime ] ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) sniffer ] ;
@ -72,6 +73,9 @@ MergeObject <libbe>storage_kit.o :
# disk device API
DiskDevice.cpp
DiskDeviceJob.cpp
DiskDeviceJobGenerator.cpp
DiskDeviceJobQueue.cpp
DiskDeviceList.cpp
DiskDevicePrivate.cpp
DiskDeviceRoster.cpp
@ -84,6 +88,9 @@ MergeObject <libbe>storage_kit.o :
Partition.cpp
PartitionDelegate.cpp
PartitioningInfo.cpp
PartitionReference.cpp
InitializeJob.cpp
;

View File

@ -23,6 +23,9 @@
#include <syscalls.h>
#include <disk_device_manager/ddm_userland_interface.h>
#include "DiskDeviceJob.h"
#include "DiskDeviceJobGenerator.h"
#include "DiskDeviceJobQueue.h"
#include "DiskSystemAddOnManager.h"
@ -276,6 +279,7 @@ status_t
BDiskDevice::CommitModifications(bool synchronously,
BMessenger progressMessenger, bool receiveCompleteProgressUpdates)
{
// TODO: Support parameters!
status_t error = InitCheck();
if (error != B_OK)
return error;
@ -283,7 +287,13 @@ BDiskDevice::CommitModifications(bool synchronously,
if (!fDelegate)
return B_BAD_VALUE;
// TODO: Implement!
// generate jobs
DiskDeviceJobQueue jobQueue;
error = DiskDeviceJobGenerator(this, &jobQueue).GenerateJobs();
// do the jobs
if (error == B_OK)
error = jobQueue.Execute();
_DeleteDelegates();
DiskSystemAddOnManager::Default()->UnloadDiskSystems();

View File

@ -0,0 +1,33 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "DiskDeviceJob.h"
#include "PartitionReference.h"
// constructor
DiskDeviceJob::DiskDeviceJob(PartitionReference* partition,
PartitionReference* child)
: fPartition(partition),
fChild(child)
{
if (fPartition)
fPartition->AddReference();
if (fChild)
fChild->AddReference();
}
// destructor
DiskDeviceJob::~DiskDeviceJob()
{
if (fPartition)
fPartition->RemoveReference();
if (fChild)
fChild->RemoveReference();
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _DISK_DEVICE_JOB_H
#define _DISK_DEVICE_JOB_H
#include <SupportDefs.h>
namespace BPrivate {
class PartitionReference;
class DiskDeviceJob {
public:
DiskDeviceJob(PartitionReference* partition,
PartitionReference* child = NULL);
virtual ~DiskDeviceJob();
virtual status_t Do() = 0;
protected:
PartitionReference* fPartition;
PartitionReference* fChild;
};
} // namespace BPrivate
using BPrivate::DiskDeviceJob;
#endif // _DISK_DEVICE_JOB_H

View File

@ -14,7 +14,12 @@
#include <disk_device_manager/ddm_userland_interface.h>
#include "DiskDeviceJob.h"
#include "DiskDeviceJobQueue.h"
#include "PartitionDelegate.h"
#include "PartitionReference.h"
#include "InitializeJob.h"
using std::nothrow;
@ -45,8 +50,8 @@ compare_string(const char* str1, const char* str2)
}
// move_info
struct DiskDeviceJobGenerator::move_info {
// MoveInfo
struct DiskDeviceJobGenerator::MoveInfo {
BPartition* partition;
off_t position;
off_t target_position;
@ -54,17 +59,38 @@ struct DiskDeviceJobGenerator::move_info {
};
// PartitionRefInfo
struct DiskDeviceJobGenerator::PartitionRefInfo {
PartitionRefInfo()
: partition(NULL),
reference(NULL)
{
}
~PartitionRefInfo()
{
if (reference)
reference->RemoveReference();
}
BPartition* partition;
PartitionReference* reference;
};
// constructor
DiskDeviceJobGenerator::DiskDeviceJobGenerator(BDiskDevice* device,
DiskDeviceJobQueue* jobQueue)
: fDevice(device),
fJobQueue(jobQueue),
fMoveInfos(NULL)
fMoveInfos(NULL),
fPartitionRefs(NULL)
{
fMoveInfoCount = fDevice->CountDescendants();
fPartitionCount = fDevice->CountDescendants();
fMoveInfos = new(nothrow) move_info[fMoveInfoCount];
// fPartitionIDs = new(nothrow) partition_id[fMoveInfoCount];
fMoveInfos = new(nothrow) MoveInfo[fPartitionCount];
// fPartitionIDs = new(nothrow) partition_id[fPartitionCount];
fPartitionRefs = new(nothrow) PartitionRefInfo[fPartitionCount];
}
@ -73,6 +99,7 @@ DiskDeviceJobGenerator::~DiskDeviceJobGenerator()
{
delete[] fMoveInfos;
// delete[] fPartitionIDs;
delete[] fPartitionRefs;
}
@ -81,10 +108,11 @@ status_t
DiskDeviceJobGenerator::GenerateJobs()
{
// check parameters
if (!fDevice || !fJobQueue /*|| !fMoveInfos || !fPartitionIDs
|| fJobQueue->Device() != fDevice || !fDevice->ShadowPartition()*/) {
if (!fDevice || !fJobQueue)
return B_BAD_VALUE;
}
if (!fMoveInfos /*|| !fPartitionIDs*/ || !fPartitionRefs)
return B_NO_MEMORY;
// 1) Generate jobs for all physical partitions that don't have an
// associated shadow partition, i.e. those that shall be deleted.
@ -116,8 +144,14 @@ DiskDeviceJobGenerator::GenerateJobs()
status_t
DiskDeviceJobGenerator::_AddJob(DiskDeviceJob* job)
{
// TODO: Implement!
return B_BAD_VALUE;
if (!job)
return B_NO_MEMORY;
status_t error = fJobQueue->AddJob(job);
if (error != B_OK)
delete job;
return error;
}
@ -208,8 +242,8 @@ DiskDeviceJobGenerator::_GenerateChildPlacementJobs(BPartition* partition)
for (int32 i = 0; BPartition* child = partition->_ChildAt(i); i++) {
if (BMutablePartition* childShadow = _GetMutablePartition(child)) {
// add a move_info for the child
move_info& info = fMoveInfos[childCount];
// add a MoveInfo for the child
MoveInfo& info = fMoveInfos[childCount];
childCount++;
info.partition = child;
info.position = child->Offset();
@ -233,7 +267,7 @@ DiskDeviceJobGenerator::_GenerateChildPlacementJobs(BPartition* partition)
// sort the move infos
if (childCount > 0 && moveForth + moveBack > 0) {
qsort(fMoveInfos, childCount, sizeof(move_info),
qsort(fMoveInfos, childCount, sizeof(MoveInfo),
_CompareMoveInfoPosition);
}
@ -243,7 +277,7 @@ DiskDeviceJobGenerator::_GenerateChildPlacementJobs(BPartition* partition)
if (moveForth < moveBack) {
// move children back
for (int32 i = 0; i < childCount; i++) {
move_info &info = fMoveInfos[i];
MoveInfo &info = fMoveInfos[i];
if (info.position > info.target_position) {
if (i == 0
|| info.target_position >= fMoveInfos[i - 1].position
@ -262,7 +296,7 @@ DiskDeviceJobGenerator::_GenerateChildPlacementJobs(BPartition* partition)
} else {
// move children forth
for (int32 i = childCount - 1; i >= 0; i--) {
move_info &info = fMoveInfos[i];
MoveInfo &info = fMoveInfos[i];
if (info.position > info.target_position) {
if (i == childCount - 1
|| info.target_position + info.size
@ -430,8 +464,23 @@ DiskDeviceJobGenerator::_GetMutablePartition(BPartition* partition)
status_t
DiskDeviceJobGenerator::_GenerateInitializeJob(BPartition* partition)
{
// TODO: Implement!
return B_BAD_VALUE;
PartitionReference* reference;
status_t error = _GetPartitionReference(partition, reference);
if (error != B_OK)
return error;
InitializeJob* job = new(nothrow) InitializeJob(reference);
if (!job)
return B_NO_MEMORY;
error = job->Init(partition->ContentType(),
partition->ContentName(), partition->ContentParameters());
if (error != B_OK) {
delete job;
return error;
}
return _AddJob(job);
}
@ -557,12 +606,52 @@ DiskDeviceJobGenerator::_CollectContentsToMove(BPartition* partition)
}
// _GetPartitionReference
status_t
DiskDeviceJobGenerator::_GetPartitionReference(BPartition* partition,
PartitionReference*& reference)
{
if (!partition)
return B_BAD_VALUE;
for (int32 i = 0; i < fPartitionCount; i++) {
PartitionRefInfo& info = fPartitionRefs[i];
if (info.partition == partition) {
reference = info.reference;
return B_OK;
}
if (info.partition == NULL) {
// create partition reference
info.reference = new(nothrow) PartitionReference();
if (!info.reference)
return B_NO_MEMORY;
// set partition ID and change counter
user_partition_data* partitionData = partition->fPartitionData;
if (partitionData) {
info.reference->SetPartitionID(partitionData->id);
info.reference->SetChangeCounter(partitionData->change_counter);
}
info.partition = partition;
reference = info.reference;
return B_OK;
}
}
// Out of slots -- that can't happen.
return B_ERROR;
}
// _CompareMoveInfoOffset
int
DiskDeviceJobGenerator::_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);
const MoveInfo* a = static_cast<const MoveInfo*>(_a);
const MoveInfo* b = static_cast<const MoveInfo*>(_b);
if (a->position < b->position)
return -1;
if (a->position > b->position)

View File

@ -18,6 +18,7 @@ namespace BPrivate {
class DiskDeviceJob;
class DiskDeviceJobQueue;
class PartitionReference;
class DiskDeviceJobGenerator {
@ -65,16 +66,21 @@ private:
status_t _CollectContentsToMove(BPartition* partition);
status_t _GetPartitionReference(BPartition* partition,
PartitionReference*& reference);
static int _CompareMoveInfoPosition(const void* _a,
const void* _b);
private:
struct move_info;
struct MoveInfo;
struct PartitionRefInfo;
BDiskDevice* fDevice;
DiskDeviceJobQueue* fJobQueue;
move_info* fMoveInfos;
int32 fMoveInfoCount;
MoveInfo* fMoveInfos;
int32 fPartitionCount;
PartitionRefInfo* fPartitionRefs;
};

View File

@ -0,0 +1,48 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "DiskDeviceJobQueue.h"
#include "DiskDeviceJob.h"
// constructor
DiskDeviceJobQueue::DiskDeviceJobQueue()
: fJobs(20, true)
{
}
// destructor
DiskDeviceJobQueue::~DiskDeviceJobQueue()
{
}
// AddJob
status_t
DiskDeviceJobQueue::AddJob(DiskDeviceJob* job)
{
if (!job)
return B_BAD_VALUE;
return fJobs.AddItem(job) ? B_OK : B_NO_MEMORY;
}
// Execute
status_t
DiskDeviceJobQueue::Execute()
{
int32 count = fJobs.CountItems();
for (int32 i = 0; i < count; i++) {
DiskDeviceJob* job = fJobs.ItemAt(i);
status_t error = job->Do();
if (error != B_OK)
return error;
}
return B_OK;
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _DISK_DEVICE_JOB_QUEUE_H
#define _DISK_DEVICE_JOB_QUEUE_H
#include <DiskDeviceDefs.h>
#include <ObjectList.h>
namespace BPrivate {
class DiskDeviceJob;
class DiskDeviceJobQueue {
public:
DiskDeviceJobQueue();
~DiskDeviceJobQueue();
status_t AddJob(DiskDeviceJob* job);
status_t Execute();
private:
typedef BObjectList<DiskDeviceJob> JobList;
JobList fJobs;
};
} // namespace BPrivate
using BPrivate::DiskDeviceJobQueue;
#endif // _DISK_DEVICE_JOB_QUEUE_H

View File

@ -0,0 +1,47 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _DISK_DEVICE_UTILS_H
#define _DISK_DEVICE_UTILS_H
#include <stdlib.h>
#include <string.h>
#include <SupportDefs.h>
namespace BPrivate {
// set_string
static inline status_t
set_string(char*& location, const char* newString)
{
char* string = NULL;
if (newString) {
string = strdup(newString);
if (!string)
return B_NO_MEMORY;
}
free(location);
location = string;
return B_OK;
}
#define SET_STRING_RETURN_ON_ERROR(location, string) \
{ \
status_t error = set_string(location, string); \
if (error != B_OK) \
return error; \
}
} // namespace BPrivate
using BPrivate::set_string;
#endif // _DISK_DEVICE_UTILS_H

View File

@ -14,38 +14,13 @@
#include <disk_device_manager/ddm_userland_interface.h>
#include "DiskDeviceUtils.h"
#include "PartitionDelegate.h"
using std::nothrow;
// set_string
static status_t
set_string(char*& location, const char* newString)
{
char* string = NULL;
if (newString) {
string = strdup(newString);
if (!string)
return B_NO_MEMORY;
}
free(location);
location = string;
return B_OK;
}
#define SET_STRING_RETURN_ON_ERROR(location, string) \
{ \
status_t error = set_string(location, string); \
if (error != B_OK) \
return error; \
}
// Offset
off_t
BMutablePartition::Offset() const

View File

@ -0,0 +1,53 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "PartitionReference.h"
// constructor
PartitionReference::PartitionReference(partition_id id, uint32 changeCounter)
: Referenceable(true), // delete when unreferenced
fID(id),
fChangeCounter(changeCounter)
{
}
// destructor
PartitionReference::~PartitionReference()
{
}
// PartitionID
partition_id
PartitionReference::PartitionID() const
{
return fID;
}
// SetPartitionID
void
PartitionReference::SetPartitionID(partition_id id)
{
fID = id;
}
// ChangeCounter
uint32
PartitionReference::ChangeCounter() const
{
return fChangeCounter;
}
// SetChangeCounter
void
PartitionReference::SetChangeCounter(uint32 counter)
{
fChangeCounter = counter;
}

View File

@ -0,0 +1,38 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _PARTITION_REFERENCE_H
#define _PARTITION_REFERENCE_H
#include <DiskDeviceDefs.h>
#include <Referenceable.h>
namespace BPrivate {
class PartitionReference : public Referenceable {
public:
PartitionReference(partition_id id = -1,
uint32 changeCounter = 0);
~PartitionReference();
partition_id PartitionID() const;
void SetPartitionID(partition_id id);
uint32 ChangeCounter() const;
void SetChangeCounter(uint32 counter);
private:
partition_id fID;
uint32 fChangeCounter;
};
} // namespace BPrivate
using BPrivate::PartitionReference;
#endif // _PARTITION_REFERENCE_H

View File

@ -0,0 +1,51 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "InitializeJob.h"
#include "DiskDeviceUtils.h"
#include "PartitionReference.h"
// constructor
InitializeJob::InitializeJob(PartitionReference* partition)
: DiskDeviceJob(partition),
fDiskSystem(NULL),
fName(NULL),
fParameters(NULL)
{
}
// destructor
InitializeJob::~InitializeJob()
{
free(fDiskSystem);
free(fName);
free(fParameters);
}
// Init
status_t
InitializeJob::Init(const char* diskSystem, const char* name,
const char* parameters)
{
SET_STRING_RETURN_ON_ERROR(fDiskSystem, diskSystem);
SET_STRING_RETURN_ON_ERROR(fName, name);
SET_STRING_RETURN_ON_ERROR(fParameters, parameters);
return B_OK;
}
// Do
status_t
InitializeJob::Do()
{
// Implement!
return B_BAD_VALUE;
}

View File

@ -0,0 +1,36 @@
/*
* Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef _INITIALIZE_JOB_H
#define _INITIALIZE_JOB_H
#include "DiskDeviceJob.h"
namespace BPrivate {
class InitializeJob : public DiskDeviceJob {
public:
InitializeJob(PartitionReference* partition);
virtual ~InitializeJob();
status_t Init(const char* diskSystem, const char* name,
const char* parameters);
virtual status_t Do();
protected:
char* fDiskSystem;
char* fName;
char* fParameters;
};
} // namespace BPrivate
using BPrivate::InitializeJob;
#endif // _INITIALIZE_JOB_H