diff --git a/src/kernel/core/disk_device_manager/jobs/KUninitializeJob.cpp b/src/kernel/core/disk_device_manager/jobs/KUninitializeJob.cpp index 31b41f3172..7f0f2f6e27 100644 --- a/src/kernel/core/disk_device_manager/jobs/KUninitializeJob.cpp +++ b/src/kernel/core/disk_device_manager/jobs/KUninitializeJob.cpp @@ -3,6 +3,11 @@ #include #include +#include +#include +#include +#include +#include #include "KUninitializeJob.h" @@ -27,8 +32,44 @@ KUninitializeJob::~KUninitializeJob() status_t KUninitializeJob::Do() { -// TODO: implement - DBG(OUT("KUninitializeJob::Do(%ld)\n", PartitionID())); +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; + } return B_OK; }