From 27d7c366591ba5233181e7485759ed38f037a4ae Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 17 Oct 2007 21:50:20 +0000 Subject: [PATCH] * Reimplemented BDiskDevice::IsModified()/ {Prepare,Commit,Cancel}Modifications() using the userland add-on backend. IsModified() and CommitModifications() are little more than stubs ATM. * Made BPartition::VisitEachChild()/VisitEachDescendant() const. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22602 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/storage/Partition.h | 10 +++- src/kits/storage/DiskDevice.cpp | 65 ++++++++++++--------- src/kits/storage/Partition.cpp | 88 ++++++++++++++++++++++++++++- 3 files changed, 132 insertions(+), 31 deletions(-) diff --git a/headers/private/storage/Partition.h b/headers/private/storage/Partition.h index 14c3b8d1a0..f8d47fc35a 100644 --- a/headers/private/storage/Partition.h +++ b/headers/private/storage/Partition.h @@ -76,9 +76,10 @@ public: status_t GetPartitioningInfo( BPartitioningInfo* info) const; - BPartition* VisitEachChild(BDiskDeviceVisitor* visitor); + BPartition* VisitEachChild(BDiskDeviceVisitor* visitor) + const; virtual BPartition* VisitEachDescendant( - BDiskDeviceVisitor* visitor); + BDiskDeviceVisitor* visitor) const; // Self Modification @@ -205,6 +206,11 @@ private: bool _SupportsChildOperation(const BPartition* child, uint32 flag) const; + status_t _CreateDelegates(); + status_t _InitDelegates(); + void _DeleteDelegates(); + bool _IsModified() const; + friend class BDiskDevice; friend class BDiskSystem; friend class BMutablePartition; diff --git a/src/kits/storage/DiskDevice.cpp b/src/kits/storage/DiskDevice.cpp index f5fe7f1634..459ef6ca0d 100644 --- a/src/kits/storage/DiskDevice.cpp +++ b/src/kits/storage/DiskDevice.cpp @@ -188,8 +188,22 @@ BDiskDevice::GetPath(BPath* path) const bool BDiskDevice::IsModified() const { - return (InitCheck() == B_OK && _IsShadow() - && _kern_is_disk_device_modified(ID())); + if (InitCheck() != B_OK) + return false; + + struct IsModifiedVisitor : public BDiskDeviceVisitor { + virtual bool Visit(BDiskDevice *device) + { + return Visit(device, 0); + } + + virtual bool Visit(BPartition *partition, int32 level) + { + return partition->_IsModified(); + } + } visitor; + + return (VisitEachDescendant(&visitor) != NULL); } @@ -209,20 +223,19 @@ BDiskDevice::PrepareModifications() status_t error = InitCheck(); if (error != B_OK) return error; - if (_IsShadow()) - return B_ERROR; + if (fDelegate) + return B_BAD_VALUE; - // ask kernel to prepare for modifications - error = _kern_prepare_disk_device_modifications(ID()); + // recursively create the delegates + error = _CreateDelegates(); + + // init them + if (error == B_OK) + error = _InitDelegates(); + + // delete all of them, if something went wrong if (error != B_OK) - return error; - - // update - error = _Update(true, NULL); - if (error != B_OK) { - // bad -- cancelling the modifications is all we can do - _kern_cancel_disk_device_modifications(ID()); - } + _DeleteDelegates(); return error; } @@ -242,15 +255,14 @@ BDiskDevice::CommitModifications(bool synchronously, status_t error = InitCheck(); if (error != B_OK) return error; - if (!_IsShadow()) + + if (!fDelegate) return B_BAD_VALUE; - // TODO: Get port and token from the progressMessenger - // TODO: Respect "synchronously"! - port_id port = -1; - int32 token = -1; - error = _kern_commit_disk_device_modifications(ID(), port, token, - receiveCompleteProgressUpdates); + // TODO: Implement! + + _DeleteDelegates(); + if (error == B_OK) error = _SetTo(ID(), true, false, 0); @@ -269,10 +281,12 @@ BDiskDevice::CancelModifications() status_t error = InitCheck(); if (error != B_OK) return error; - if (!_IsShadow()) + + if (!fDelegate) return B_BAD_VALUE; - error = _kern_cancel_disk_device_modifications(ID()); + _DeleteDelegates(); + if (error == B_OK) error = _SetTo(ID(), true, false, 0); @@ -317,8 +331,7 @@ BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow, status_t error = B_OK; do { error = _kern_get_disk_device_data(id, deviceOnly, shadow, - (user_disk_device_data*)buffer, - bufferSize, &neededSize); + (user_disk_device_data*)buffer, bufferSize, &neededSize); if (error == B_BUFFER_OVERFLOW) { // buffer to small re-allocate it if (buffer) @@ -346,7 +359,7 @@ BDiskDevice::_GetData(partition_id id, bool deviceOnly, bool shadow, // _SetTo status_t BDiskDevice::_SetTo(partition_id id, bool deviceOnly, bool shadow, - size_t neededSize) + size_t neededSize) { Unset(); diff --git a/src/kits/storage/Partition.cpp b/src/kits/storage/Partition.cpp index e1010bc28d..fc8bd19b13 100644 --- a/src/kits/storage/Partition.cpp +++ b/src/kits/storage/Partition.cpp @@ -641,7 +641,7 @@ BPartition::GetPartitioningInfo(BPartitioningInfo* info) const // VisitEachChild BPartition* -BPartition::VisitEachChild(BDiskDeviceVisitor* visitor) +BPartition::VisitEachChild(BDiskDeviceVisitor* visitor) const { if (visitor) { int32 level = _Level(); @@ -656,10 +656,10 @@ BPartition::VisitEachChild(BDiskDeviceVisitor* visitor) // VisitEachDescendant BPartition* -BPartition::VisitEachDescendant(BDiskDeviceVisitor* visitor) +BPartition::VisitEachDescendant(BDiskDeviceVisitor* visitor) const { if (visitor) - return _VisitEachDescendant(visitor); + return const_cast(this)->_VisitEachDescendant(visitor); return NULL; } @@ -1500,3 +1500,85 @@ BPartition::_SupportsChildOperation(const BPartition* child, uint32 flag) const return supported & flag; } + +// _CreateDelegates +status_t +BPartition::_CreateDelegates() +{ + if (fDelegate || !fPartitionData) + return B_BAD_VALUE; + + // create and init delegate + fDelegate = new(nothrow) Delegate(this); + if (!fDelegate) + return B_NO_MEMORY; + + status_t error = fDelegate->InitHierarchy(fPartitionData, + fParent ? fParent->fDelegate : NULL); + if (error != B_OK) + return error; + + // create child delegates + int32 count = fPartitionData->child_count; + for (int32 i = 0; i < count; i++) { + BPartition* child = (BPartition*)fPartitionData->children[i]->user_data; + error = child->_CreateDelegates(); + if (error != B_OK) + return error; + } + + return B_OK; +} + + +// _InitDelegates +status_t +BPartition::_InitDelegates() +{ + // init delegate + status_t error = fDelegate->InitAfterHierarchy(); + if (error != B_OK) + return error; + + // recursively init child delegates + int32 count = CountChildren(); + for (int32 i = 0; i < count; i++) { + error = ChildAt(i)->_InitDelegates(); + if (error != B_OK) + return error; + } + + return B_OK; +} + + +// _DeleteDelegates +void +BPartition::_DeleteDelegates() +{ + // recursively delete child delegates + int32 count = CountChildren(); + for (int32 i = count - 1; i >= 0; i--) + ChildAt(i)->_DeleteDelegates(); + + // delete delegate + delete fDelegate; + fDelegate = NULL; + + // Commit suicide, if the delegate was our only link to reality (i.e. + // there's no physically existing partition we represent). + if (fPartitionData == NULL) + delete this; +} + + +// _IsModified +bool +BPartition::_IsModified() const +{ + if (!fDelegate) + return false; + + // TODO: Implement! + return false; +}