Implemented the resize job.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4870 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2003-09-29 21:44:47 +00:00
parent b0814f61c3
commit 58b7de1cda
2 changed files with 87 additions and 8 deletions
@@ -3,7 +3,14 @@
#include <stdio.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
@@ -13,11 +20,11 @@
// constructor
KResizeJob::KResizeJob(partition_id parentID, partition_id partitionID,
off_t size, bool resizeContents)
off_t size)
: KDiskDeviceJob(B_DISK_DEVICE_JOB_RESIZE, partitionID, parentID),
fResizeContents(resizeContents)
fSize(size)
{
SetDescription("uninitializing partition");
SetDescription("resizing partition");
}
// destructor
@@ -29,8 +36,81 @@ KResizeJob::~KResizeJob()
status_t
KResizeJob::Do()
{
// TODO: implement
DBG(OUT("KResizeJob::Do(%ld)\n", PartitionID()));
return B_OK;
// 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;
}
} else {
SetErrorMessage("Couldn't find partition.");
return B_ENTRY_NOT_FOUND;
}
// cannot come here
return B_ERROR;
}
@@ -10,14 +10,13 @@ namespace DiskDevice {
class KResizeJob : public KDiskDeviceJob {
public:
KResizeJob(partition_id parentID, partition_id partitionID, off_t size,
bool resizeContents);
KResizeJob(partition_id parentID, partition_id partitionID, off_t size);
virtual ~KResizeJob();
virtual status_t Do();
private:
bool fResizeContents;
off_t fSize;
};
} // namespace DiskDevice