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