From a162af3b0eefe4930a6816c02ec436792cc45bdb Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 4 Jul 2003 23:45:26 +0000 Subject: [PATCH] Made KPartition abstract and derived two classes, KPhysicalPartition and KShadowPartition from it. KPhysicalPartition represents a partition that exists on-disk, while KShadowPartition is a partition edited by the API user, but not yet written to disk. Related changes in other classes. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3851 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/disk_device_manager/KDiskDevice.h | 6 +- .../disk_device_manager/KDiskDeviceManager.h | 22 +- .../disk_device_manager/KFileDiskDevice.h | 2 - .../kernel/disk_device_manager/KPartition.h | 23 +- .../disk_device_manager/KPhysicalPartition.h | 55 ++++ .../disk_device_manager/KShadowPartition.h | 41 +++ src/kernel/core/disk_device_manager/Jamfile | 4 +- .../core/disk_device_manager/KDiskDevice.cpp | 14 +- .../KDiskDeviceManager.cpp | 34 ++- .../disk_device_manager/KFileDiskDevice.cpp | 8 - .../core/disk_device_manager/KPartition.cpp | 51 +--- .../KPhysicalPartition.cpp | 236 ++++++++++++++++++ .../disk_device_manager/KShadowPartition.cpp | 97 +++++++ 13 files changed, 481 insertions(+), 112 deletions(-) create mode 100644 headers/private/kernel/disk_device_manager/KPhysicalPartition.h create mode 100644 headers/private/kernel/disk_device_manager/KShadowPartition.h create mode 100644 src/kernel/core/disk_device_manager/KPhysicalPartition.cpp create mode 100644 src/kernel/core/disk_device_manager/KShadowPartition.cpp diff --git a/headers/private/kernel/disk_device_manager/KDiskDevice.h b/headers/private/kernel/disk_device_manager/KDiskDevice.h index 9e4849a56a..7a73686d7f 100644 --- a/headers/private/kernel/disk_device_manager/KDiskDevice.h +++ b/headers/private/kernel/disk_device_manager/KDiskDevice.h @@ -5,7 +5,7 @@ #include -#include "KPartition.h" +#include "KPhysicalPartition.h" #include "RWLocker.h" // disk device flags @@ -18,7 +18,7 @@ enum { namespace BPrivate { namespace DiskDevice { -class KDiskDevice : public KPartition { +class KDiskDevice : public KPhysicalPartition { public: KDiskDevice(partition_id id = -1); virtual ~KDiskDevice(); @@ -66,8 +66,6 @@ public: disk_device_data *DeviceData(); const disk_device_data *DeviceData() const; - virtual KPartition *CreateShadowPartition(); - void SetShadowOwner(team_id team); team_id ShadowOwner() const; diff --git a/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h b/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h index 5a8df4c738..0d04ef2874 100644 --- a/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h +++ b/headers/private/kernel/disk_device_manager/KDiskDeviceManager.h @@ -37,20 +37,18 @@ public: // Disk Device / Partition Management // manager must be locked - KDiskDevice *FindDevice(const char *path, bool noShadow = true); - KDiskDevice *FindDevice(partition_id id, bool noShadow = true); - KPartition *FindPartition(const char *path, bool noShadow = true); - KPartition *FindPartition(partition_id id, bool noShadow = true); - KFileDiskDevice *FindFileDevice(const char *filePath, - bool noShadow = true); + KDiskDevice *FindDevice(const char *path); + KDiskDevice *FindDevice(partition_id id); + KPartition *FindPartition(const char *path, bool noShadow = false); + KPartition *FindPartition(partition_id id, bool noShadow = false); + KFileDiskDevice *FindFileDevice(const char *filePath); - KDiskDevice *RegisterDevice(const char *path, bool noShadow = true); - KDiskDevice *RegisterDevice(partition_id id, bool noShadow = true); + KDiskDevice *RegisterDevice(const char *path); + KDiskDevice *RegisterDevice(partition_id id); KDiskDevice *RegisterNextDevice(int32 *cookie); - KPartition *RegisterPartition(const char *path, bool noShadow = true); - KPartition *RegisterPartition(partition_id id, bool noShadow = true); - KFileDiskDevice *RegisterFileDevice(const char *filePath, - bool noShadow = true); + KPartition *RegisterPartition(const char *path, bool noShadow = false); + KPartition *RegisterPartition(partition_id id, bool noShadow = false); + KFileDiskDevice *RegisterFileDevice(const char *filePath); status_t CreateFileDevice(const char *filePath, partition_id *device = 0); status_t DeleteFileDevice(const char *filePath); diff --git a/headers/private/kernel/disk_device_manager/KFileDiskDevice.h b/headers/private/kernel/disk_device_manager/KFileDiskDevice.h index 12f23a4822..20ad20a00a 100644 --- a/headers/private/kernel/disk_device_manager/KFileDiskDevice.h +++ b/headers/private/kernel/disk_device_manager/KFileDiskDevice.h @@ -22,8 +22,6 @@ public: const char *FilePath() const; - virtual KPartition *CreateShadowPartition(); - // virtual void Dump(bool deep = true, int32 level = 0); private: diff --git a/headers/private/kernel/disk_device_manager/KPartition.h b/headers/private/kernel/disk_device_manager/KPartition.h index 9a848c9d9c..b27391abc5 100644 --- a/headers/private/kernel/disk_device_manager/KPartition.h +++ b/headers/private/kernel/disk_device_manager/KPartition.h @@ -24,6 +24,8 @@ namespace DiskDevice { class KDiskDevice; class KDiskSystem; +class KPhysicalPartition; +class KShadowPartition; class KPartition { public: @@ -44,7 +46,7 @@ public: virtual bool PrepareForRemoval(); virtual bool PrepareForDeletion(); - status_t Open(int flags, int *fd); + virtual status_t Open(int flags, int *fd); virtual status_t PublishDevice(); virtual status_t UnpublishDevice(); @@ -55,7 +57,7 @@ public: bool IsDescendantBusy() const; // == jobs which may affect a descendant of this partition are // scheduled/in progress; IsBusy() => IsDescendantBusy() - // In the userland API, both can probably mapped to one flag. + // In the userland API, both can probably be mapped to one flag. void SetOffset(off_t offset); off_t Offset() const; // 0 for devices @@ -108,8 +110,8 @@ public: void SetVolumeID(dev_t volumeID); dev_t VolumeID() const; - status_t Mount(uint32 mountFlags, const char *parameters); - status_t Unmount(); + virtual status_t Mount(uint32 mountFlags, const char *parameters); + virtual status_t Unmount(); // Parameters @@ -128,8 +130,8 @@ public: KPartition *Parent() const; status_t AddChild(KPartition *partition, int32 index = -1); - status_t CreateChild(partition_id id, int32 index, - KPartition **child = NULL); + virtual status_t CreateChild(partition_id id, int32 index, + KPartition **child = NULL) = 0; bool RemoveChild(int32 index); bool RemoveChild(KPartition *child); bool RemoveAllChildren(); @@ -138,10 +140,11 @@ public: // Shadow Partition - virtual KPartition *CreateShadowPartition(); // creates a complete tree - void DeleteShadowPartition(); // deletes ... - KPartition *ShadowPartition() const; - bool IsShadowPartition() const; + virtual status_t CreateShadowPartition(); // creates a complete tree + virtual void DeleteShadowPartition(); // deletes ... + virtual KShadowPartition *ShadowPartition() = 0; + virtual bool IsShadowPartition() const = 0; + virtual KPhysicalPartition *PhysicalPartition() = 0; // DiskSystem diff --git a/headers/private/kernel/disk_device_manager/KPhysicalPartition.h b/headers/private/kernel/disk_device_manager/KPhysicalPartition.h new file mode 100644 index 0000000000..cc03d3c535 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KPhysicalPartition.h @@ -0,0 +1,55 @@ +// KPartition.h + +#ifndef _K_DISK_DEVICE_PHYSICAL_PARTITION_H +#define _K_DISK_DEVICE_PHYSICAL_PARTITION_H + +#include + +namespace BPrivate { +namespace DiskDevice { + +class KDiskDevice; +class KDiskSystem; +class KShadowPartition; + +class KPhysicalPartition : public KPartition { +public: + KPhysicalPartition(partition_id id = -1); + virtual ~KPhysicalPartition(); + + virtual bool PrepareForRemoval(); + + virtual status_t Open(int flags, int *fd); + virtual status_t PublishDevice(); + virtual status_t UnpublishDevice(); + + virtual status_t Mount(uint32 mountFlags, const char *parameters); + virtual status_t Unmount(); + + // Hierarchy + + virtual status_t CreateChild(partition_id id, int32 index, + KPartition **child = NULL); + + // Shadow Partition + + virtual status_t CreateShadowPartition(); // creates a complete tree + virtual void DeleteShadowPartition(); // deletes ... + virtual KShadowPartition *ShadowPartition(); + virtual bool IsShadowPartition() const; + virtual KPhysicalPartition *PhysicalPartition(); + + // DiskSystem + + virtual void Dump(bool deep, int32 level); + +protected: + KShadowPartition *fShadowPartition; +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KPhysicalPartition; + +#endif // _K_DISK_DEVICE_PHYSICAL_PARTITION_H diff --git a/headers/private/kernel/disk_device_manager/KShadowPartition.h b/headers/private/kernel/disk_device_manager/KShadowPartition.h new file mode 100644 index 0000000000..c96aee0a61 --- /dev/null +++ b/headers/private/kernel/disk_device_manager/KShadowPartition.h @@ -0,0 +1,41 @@ +// KPartition.h + +#ifndef _K_DISK_DEVICE_SHADOW_PARTITION_H +#define _K_DISK_DEVICE_SHADOW_PARTITION_H + +#include "KPartition.h" + +namespace BPrivate { +namespace DiskDevice { + +class KPhysicalPartition; + +class KShadowPartition : public KPartition { +public: + KShadowPartition(KPhysicalPartition *physicalPartition); + virtual ~KShadowPartition(); + + // Hierarchy + + virtual status_t CreateChild(partition_id id, int32 index, + KPartition **child = NULL); + + // Shadow Partition + + virtual KShadowPartition *ShadowPartition(); + virtual bool IsShadowPartition() const; + void SetPhysicalPartition(KPhysicalPartition *partition); + virtual KPhysicalPartition *PhysicalPartition(); + + virtual void Dump(bool deep, int32 level); + +protected: + KPhysicalPartition *fPhysicalPartition; +}; + +} // namespace DiskDevice +} // namespace BPrivate + +using BPrivate::DiskDevice::KShadowPartition; + +#endif // _K_DISK_DEVICE_SHADOW_PARTITION_H diff --git a/src/kernel/core/disk_device_manager/Jamfile b/src/kernel/core/disk_device_manager/Jamfile index 33e74b873c..1629bd5388 100644 --- a/src/kernel/core/disk_device_manager/Jamfile +++ b/src/kernel/core/disk_device_manager/Jamfile @@ -11,6 +11,7 @@ UsePrivateHeaders [ FDirName storage ] ; UseHeaders [ FDirName $(OBOS_TOP) src tests kits storage virtualdrive ] ; SharedLibrary disk_device_manager : + disk_device_manager.cpp KDiskDevice.cpp KDiskDeviceJob.cpp KDiskDeviceJobFactory.cpp @@ -21,7 +22,8 @@ SharedLibrary disk_device_manager : KFileSystem.cpp KPartition.cpp KPartitioningSystem.cpp - disk_device_manager.cpp + KPhysicalPartition.cpp + KShadowPartition.cpp # jobs KCreateChildJob.cpp diff --git a/src/kernel/core/disk_device_manager/KDiskDevice.cpp b/src/kernel/core/disk_device_manager/KDiskDevice.cpp index 35d5ba948c..95b01d34bc 100644 --- a/src/kernel/core/disk_device_manager/KDiskDevice.cpp +++ b/src/kernel/core/disk_device_manager/KDiskDevice.cpp @@ -17,7 +17,7 @@ // constructor KDiskDevice::KDiskDevice(partition_id id) - : KPartition(id), + : KPhysicalPartition(id), fDeviceData(), fLocker("diskdevice"), fFD(-1), @@ -143,7 +143,7 @@ KDiskDevice::IsWriteLocked() void KDiskDevice::SetID(partition_id id) { - KPartition::SetID(id); + KPhysicalPartition::SetID(id); fDeviceData.id = id; } @@ -248,14 +248,6 @@ KDiskDevice::DeviceData() const return &fDeviceData; } -// CreateShadowPartition -KPartition * -KDiskDevice::CreateShadowPartition() -{ - // not implemented - return NULL; -} - // SetShadowOwner void KDiskDevice::SetShadowOwner(team_id team) @@ -278,7 +270,7 @@ KDiskDevice::Dump(bool deep, int32 level) OUT(" media status: %s\n", strerror(fMediaStatus)); OUT(" device flags: %lx\n", DeviceFlags()); if (fMediaStatus == B_OK) - KPartition::Dump(deep, 0); + KPhysicalPartition::Dump(deep, 0); } // GetMediaStatus diff --git a/src/kernel/core/disk_device_manager/KDiskDeviceManager.cpp b/src/kernel/core/disk_device_manager/KDiskDeviceManager.cpp index 1e61b8a157..6b312bb0f2 100644 --- a/src/kernel/core/disk_device_manager/KDiskDeviceManager.cpp +++ b/src/kernel/core/disk_device_manager/KDiskDeviceManager.cpp @@ -203,9 +203,8 @@ KDiskDeviceManager::Unlock() // FindDevice KDiskDevice * -KDiskDeviceManager::FindDevice(const char *path, bool noShadow) +KDiskDeviceManager::FindDevice(const char *path) { -// TODO: Handle shadows correctly! for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie); ) { if (device->Path() && !strcmp(path, device->Path())) return device; @@ -215,9 +214,8 @@ KDiskDeviceManager::FindDevice(const char *path, bool noShadow) // FindDevice KDiskDevice * -KDiskDeviceManager::FindDevice(partition_id id, bool noShadow) +KDiskDeviceManager::FindDevice(partition_id id) { -// TODO: Handle shadows correctly! if (KPartition *partition = FindPartition(id)) return partition->Device(); return NULL; @@ -227,7 +225,6 @@ KDiskDeviceManager::FindDevice(partition_id id, bool noShadow) KPartition * KDiskDeviceManager::FindPartition(const char *path, bool noShadow) { -// TODO: Handle shadows correctly! // TODO: Optimize! for (PartitionMap::Iterator it = fPartitions->Begin(); it != fPartitions->End(); @@ -236,6 +233,8 @@ KDiskDeviceManager::FindPartition(const char *path, bool noShadow) char partitionPath[B_PATH_NAME_LENGTH]; if (partition->GetPath(partitionPath) == B_OK && !strcmp(path, partitionPath)) { + if (noShadow && partition->IsShadowPartition()) + return partition->PhysicalPartition(); return partition; } } @@ -246,18 +245,19 @@ KDiskDeviceManager::FindPartition(const char *path, bool noShadow) KPartition * KDiskDeviceManager::FindPartition(partition_id id, bool noShadow) { -// TODO: Handle shadows correctly! PartitionMap::Iterator it = fPartitions->Find(id); - if (it != fPartitions->End()) + if (it != fPartitions->End()) { + if (noShadow && it->Value()->IsShadowPartition()) + return it->Value()->PhysicalPartition(); return it->Value(); + } return NULL; } // FindFileDevice KFileDiskDevice * -KDiskDeviceManager::FindFileDevice(const char *filePath, bool noShadow) +KDiskDeviceManager::FindFileDevice(const char *filePath) { -// TODO: Handle shadows correctly! for (int32 cookie = 0; KDiskDevice *device = NextDevice(&cookie); ) { KFileDiskDevice *fileDevice = dynamic_cast(device); if (fileDevice && fileDevice->FilePath() @@ -270,11 +270,10 @@ KDiskDeviceManager::FindFileDevice(const char *filePath, bool noShadow) // RegisterDevice KDiskDevice * -KDiskDeviceManager::RegisterDevice(const char *path, bool noShadow) +KDiskDeviceManager::RegisterDevice(const char *path) { -// TODO: Handle shadows correctly! if (ManagerLocker locker = this) { - if (KDiskDevice *device = FindDevice(path, noShadow)) { + if (KDiskDevice *device = FindDevice(path)) { device->Register(); return device; } @@ -284,11 +283,10 @@ KDiskDeviceManager::RegisterDevice(const char *path, bool noShadow) // RegisterDevice KDiskDevice * -KDiskDeviceManager::RegisterDevice(partition_id id, bool noShadow) +KDiskDeviceManager::RegisterDevice(partition_id id) { -// TODO: Handle shadows correctly! if (ManagerLocker locker = this) { - if (KDiskDevice *device = FindDevice(id, noShadow)) { + if (KDiskDevice *device = FindDevice(id)) { device->Register(); return device; } @@ -339,10 +337,10 @@ KDiskDeviceManager::RegisterPartition(partition_id id, bool noShadow) // RegisterFileDevice KFileDiskDevice * -KDiskDeviceManager::RegisterFileDevice(const char *filePath, bool noShadow) +KDiskDeviceManager::RegisterFileDevice(const char *filePath) { if (ManagerLocker locker = this) { - if (KFileDiskDevice *device = FindFileDevice(filePath, noShadow)) { + if (KFileDiskDevice *device = FindFileDevice(filePath)) { device->Register(); return device; } @@ -572,8 +570,6 @@ KDiskDeviceManager::LoadNextDiskSystem(int32 *cookie) if (!cookie) return NULL; if (ManagerLocker locker = this) { - // TODO: This loop assumes that the disk system list is ordered. - // Make sure that this is really the case. if (KDiskSystem *diskSystem = NextDiskSystem(cookie)) { if (diskSystem->Load() == B_OK) { *cookie = diskSystem->ID() + 1; diff --git a/src/kernel/core/disk_device_manager/KFileDiskDevice.cpp b/src/kernel/core/disk_device_manager/KFileDiskDevice.cpp index 801cccee48..86ef5c03e7 100644 --- a/src/kernel/core/disk_device_manager/KFileDiskDevice.cpp +++ b/src/kernel/core/disk_device_manager/KFileDiskDevice.cpp @@ -118,14 +118,6 @@ KFileDiskDevice::FilePath() const return fFilePath; } -// CreateShadowPartition -KPartition * -KFileDiskDevice::CreateShadowPartition() -{ - // not implemented - return NULL; -} - // _RegisterDevice status_t KFileDiskDevice::_RegisterDevice(const char *file, const char *device) diff --git a/src/kernel/core/disk_device_manager/KPartition.cpp b/src/kernel/core/disk_device_manager/KPartition.cpp index a7e2358c21..58d393ce17 100644 --- a/src/kernel/core/disk_device_manager/KPartition.cpp +++ b/src/kernel/core/disk_device_manager/KPartition.cpp @@ -18,12 +18,12 @@ using namespace std; -// constructor // debugging //#define DBG(x) #define DBG(x) x #define OUT printf +// constructor KPartition::KPartition(partition_id id) : fPartitionData(), fChildren(), @@ -446,7 +446,7 @@ KPartition::GetPath(char *path) const int32 len = strlen(path); if (len >= B_PATH_NAME_LENGTH - 10) return B_NAME_TOO_LONG; - if (Parent() == Device()) { + if (Parent()->IsDevice()) { // Our parent is a device, so we replace `raw' by our index. int32 leafLen = strlen("/raw"); if (len <= leafLen || strcmp(path + len - leafLen, "/raw")) @@ -579,29 +579,6 @@ KPartition::AddChild(KPartition *partition, int32 index) return B_ERROR; } -// CreateChild -status_t -KPartition::CreateChild(partition_id id, int32 index, KPartition **_child) -{ - // check parameters - int32 count = fPartitionData.child_count; - if (index == -1) - index = count; - if (index < 0 || index > count) - return B_BAD_VALUE; - // create and add partition - KPartition *child = new(nothrow) KPartition(id); - if (!child) - return B_NO_MEMORY; - status_t error = AddChild(child, index); - // cleanup / set result - if (error != B_OK) - delete child; - else if (_child) - *_child = child; - return error; -} - // RemoveChild bool KPartition::RemoveChild(int32 index) @@ -666,34 +643,18 @@ KPartition::CountChildren() const } // CreateShadowPartition -KPartition * +status_t KPartition::CreateShadowPartition() { - // not implemented - return NULL; + // implemented by derived classes + return B_ERROR; } // DeleteShadowPartition void KPartition::DeleteShadowPartition() { - // not implemented -} - -// ShadowPartition -KPartition * -KPartition::ShadowPartition() const -{ - // not implemented - return NULL; -} - -// IsShadowPartition -bool -KPartition::IsShadowPartition() const -{ - // not implemented - return false; + // implemented by derived classes } // SetDiskSystem diff --git a/src/kernel/core/disk_device_manager/KPhysicalPartition.cpp b/src/kernel/core/disk_device_manager/KPhysicalPartition.cpp new file mode 100644 index 0000000000..0eaf9dcef0 --- /dev/null +++ b/src/kernel/core/disk_device_manager/KPhysicalPartition.cpp @@ -0,0 +1,236 @@ +// KPhysicalPartition.cpp + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "KDiskDevice.h" +#include "KDiskDeviceManager.h" +#include "KDiskDeviceUtils.h" +#include "KPhysicalPartition.h" +#include "KShadowPartition.h" + +using namespace std; + +// debugging +//#define DBG(x) +#define DBG(x) x +#define OUT printf + +// constructor +KPhysicalPartition::KPhysicalPartition(partition_id id) + : KPartition(id), + fShadowPartition(NULL) +{ +} + +// destructor +KPhysicalPartition::~KPhysicalPartition() +{ +} + +// Register +// PrepareForRemoval +bool +KPhysicalPartition::PrepareForRemoval() +{ + bool result = KPartition::PrepareForRemoval(); + if (result) { + DeleteShadowPartition(); + UnpublishDevice(); + } + return result; +} + +// Open +status_t +KPhysicalPartition::Open(int flags, int *fd) +{ + if (!fd) + return B_BAD_VALUE; + // get the path + char path[B_PATH_NAME_LENGTH]; + status_t error = GetPath(path); + if (error != B_OK) + return error; + // open the device + *fd = open(path, flags); + if (*fd < 0) + return errno; + return B_OK; +} + +// PublishDevice +status_t +KPhysicalPartition::PublishDevice() +{ + // prepare a partition_info + partition_info info; + info.offset = Offset(); + info.size = Size(); + info.logical_block_size = BlockSize(); + info.session = 0; + info.partition = ID(); + if (strlen(Device()->Path()) >= 256) + return B_NAME_TOO_LONG; + strcpy(info.device, Device()->Path()); + // get the entry path + char path[B_PATH_NAME_LENGTH]; + status_t error = GetPath(path); + if (error != B_OK) + return error; + // create the entry + int fd = creat(path, 0666); + if (fd < 0) + return errno; + // set the partition info + error = B_OK; + if (ioctl(fd, B_SET_PARTITION, &info) < 0) + error = errno; + close(fd); + return error; +} + +// UnpublishDevice +status_t +KPhysicalPartition::UnpublishDevice() +{ + // get the entry path + char path[B_PATH_NAME_LENGTH]; + status_t error = GetPath(path); + if (error != B_OK) + return error; + // remove the entry + if (remove(path) < 0) + return errno; + return B_OK; +} + +// Mount +status_t +KPhysicalPartition::Mount(uint32 mountFlags, const char *parameters) +{ + // not implemented + return B_ERROR; +} + +// Unmount +status_t +KPhysicalPartition::Unmount() +{ + // not implemented + return B_ERROR; +} + +// CreateChild +status_t +KPhysicalPartition::CreateChild(partition_id id, int32 index, + KPartition **_child) +{ + // check parameters + int32 count = fPartitionData.child_count; + if (index == -1) + index = count; + if (index < 0 || index > count) + return B_BAD_VALUE; + // create and add partition + KPhysicalPartition *child = new(nothrow) KPhysicalPartition(id); + if (!child) + return B_NO_MEMORY; + status_t error = AddChild(child, index); + // cleanup / set result + if (error != B_OK) + delete child; + else if (_child) + *_child = child; + return error; +} + +// CreateShadowPartition +status_t +KPhysicalPartition::CreateShadowPartition() +{ + if (fShadowPartition) + return B_BAD_VALUE; + KDiskDeviceManager *manager = KDiskDeviceManager::Default(); + if (ManagerLocker locker = manager) { + // create shadow partition + fShadowPartition = new(nothrow) KShadowPartition(this); + if (!fShadowPartition) + return B_NO_MEMORY; + // make it known to the manager + if (!manager->PartitionAdded(fShadowPartition)) { + delete fShadowPartition; + fShadowPartition = NULL; + return B_NO_MEMORY; + } + } + // create shadows for children + for (int32 i = 0; KPartition *child = ChildAt(i); i++) { + status_t error = child->CreateShadowPartition(); + if (error == B_OK) + error = fShadowPartition->AddChild(child->ShadowPartition(), i); + // cleanup on error + if (error != B_OK) { + for (int32 k = 0; k <= i; i++) + ChildAt(k)->DeleteShadowPartition(); + DeleteShadowPartition(); + return error; + } + } + return B_OK; +} + +// DeleteShadowPartition +void +KPhysicalPartition::DeleteShadowPartition() +{ + if (!fShadowPartition) + return; + // delete children's shadows + for (int32 i = 0; KPartition *child = ChildAt(i); i++) + child->DeleteShadowPartition(); + // delete the thing + KDiskDeviceManager *manager = KDiskDeviceManager::Default(); + if (ManagerLocker locker = manager) { + fShadowPartition->SetPhysicalPartition(NULL); + PartitionRegistrar _(fShadowPartition); + manager->PartitionRemoved(fShadowPartition); + fShadowPartition = NULL; + } +} + +// ShadowPartition +KShadowPartition * +KPhysicalPartition::ShadowPartition() +{ + return fShadowPartition; +} + +// IsShadowPartition +bool +KPhysicalPartition::IsShadowPartition() const +{ + return false; +} + +// PhysicalPartition +KPhysicalPartition * +KPhysicalPartition::PhysicalPartition() +{ + return this; +} + +// Dump +void +KPhysicalPartition::Dump(bool deep, int32 level) +{ + KPartition::Dump(deep, level); +} + diff --git a/src/kernel/core/disk_device_manager/KShadowPartition.cpp b/src/kernel/core/disk_device_manager/KShadowPartition.cpp new file mode 100644 index 0000000000..91fc91a0d6 --- /dev/null +++ b/src/kernel/core/disk_device_manager/KShadowPartition.cpp @@ -0,0 +1,97 @@ +// KShadowPartition.cpp + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "KDiskDevice.h" +#include "KDiskDeviceManager.h" +#include "KDiskDeviceUtils.h" +#include "KShadowPartition.h" + +using namespace std; + +// debugging +//#define DBG(x) +#define DBG(x) x +#define OUT printf + +// constructor +KShadowPartition::KShadowPartition(KPhysicalPartition *partition) + : KPartition(), + fPhysicalPartition(NULL) +{ + SetPhysicalPartition(partition); +} + +// destructor +KShadowPartition::~KShadowPartition() +{ +} + +// CreateChild +status_t +KShadowPartition::CreateChild(partition_id id, int32 index, + KPartition **_child) +{ + // check parameters + int32 count = fPartitionData.child_count; + if (index == -1) + index = count; + if (index < 0 || index > count) + return B_BAD_VALUE; + // create and add partition + KShadowPartition *child = new(nothrow) KShadowPartition(NULL); + if (!child) + return B_NO_MEMORY; + status_t error = AddChild(child, index); + // cleanup / set result + if (error != B_OK) + delete child; + else if (_child) + *_child = child; + return error; +} + +// IsShadowPartition +bool +KShadowPartition::IsShadowPartition() const +{ + return true; +} + +// ShadowPartition +KShadowPartition* +KShadowPartition::ShadowPartition() +{ + return this; +} + +// SetPhysicalPartition +void +KShadowPartition::SetPhysicalPartition(KPhysicalPartition *partition) +{ + fPhysicalPartition = partition; +// TODO: clone the data of the physical partition. +} + +// PhysicalPartition +KPhysicalPartition* +KShadowPartition::PhysicalPartition() +{ + return fPhysicalPartition; +} + +// Dump +void +KShadowPartition::Dump(bool deep, int32 level) +{ + KPartition::Dump(deep, level); +} +