From d61adbe2444676df399f25b762a07aeb72e1f7e9 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 21 Jul 2003 14:17:33 +0000 Subject: [PATCH] CanMove() returns a list of partitions to be unmounted for moving, now. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4041 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/storage/Partition.h | 2 +- src/kits/storage/Partition.cpp | 86 +++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 24 deletions(-) diff --git a/headers/private/storage/Partition.h b/headers/private/storage/Partition.h index 44bb4abf4b..a36da525fb 100644 --- a/headers/private/storage/Partition.h +++ b/headers/private/storage/Partition.h @@ -81,7 +81,7 @@ public: status_t Resize(off_t size, bool resizeContents = true); bool CanMove(BObjectList *unmovableDescendants, - bool *whileMounted = NULL) const; + BObjectList *movableOnlyIfUnmounted) const; status_t ValidateMove(off_t *newOffset, bool force = false) const; status_t Move(off_t newOffset, bool force = false); diff --git a/src/kits/storage/Partition.cpp b/src/kits/storage/Partition.cpp index 1ce732641f..687411c440 100644 --- a/src/kits/storage/Partition.cpp +++ b/src/kits/storage/Partition.cpp @@ -27,6 +27,33 @@ (\see IsEmpty()). */ +// AutoDeleter +/*! \brief Helper class deleting objects automatically. +*/ +template +class AutoDeleter { +public: + inline AutoDeleter(C *data = NULL, bool array = false) + : fData(data), fArray(array) {} + + inline ~AutoDeleter() + { + if (fArray) + delete[] fData; + else + delete fData; + } + + inline void SetTo(C *data, bool array = false) + { + fData = data; + fArray = array; + } + + C *fData; + bool fArray; +}; + // constructor BPartition::BPartition() : fDevice(NULL), @@ -479,38 +506,51 @@ BPartition::Resize(off_t size, bool resizeContents) // CanMove bool BPartition::CanMove(BObjectList *unmovableDescendants, - bool *whileMounted) const + BObjectList *movableOnlyIfUnmounted) const { // check parameters - if (!unmovableDescendants || !fPartitionData || IsDevice() || !Parent() - || !_IsShadow()) { + if (!unmovableDescendants || !movableOnlyIfUnmounted || !fPartitionData + || IsDevice() || !Parent() || !_IsShadow()) { return false; } - // count descendants and allocate a partition_id array large enough + // count descendants and allocate partition_id arrays large enough int32 descendantCount = _CountDescendants(); - partition_id *descendants = NULL; + partition_id *unmovableIDs = NULL; + partition_id *needUnmountingIDs = NULL; + AutoDeleter deleter1; + AutoDeleter deleter2; if (descendantCount > 0) { - descendants = new(nothrow) partition_id[descendantCount]; - if (!descendants) + // allocate arrays + unmovableIDs = new(nothrow) partition_id[descendantCount]; + needUnmountingIDs = new(nothrow) partition_id[descendantCount]; + deleter1.SetTo(unmovableIDs, true); + deleter2.SetTo(needUnmountingIDs, true); + if (!unmovableIDs || !needUnmountingIDs) return false; - for (int32 i = 0; i < descendantCount; i++) - descendants[i] = -1; - } - // get the info - bool result = _kern_supports_moving_partition(_ShadowID(), descendants, - descendantCount, whileMounted); - if (result) { - // find BPartition objects for returned IDs - for (int32 i = 0; i < descendantCount && descendants[i] != -1; i++) { - BPartition *descendant = FindDescendant(descendants[i]); - if (!descendant || !unmovableDescendants->AddItem(descendant)) { - result = false; - break; - } + // init arrays + for (int32 i = 0; i < descendantCount; i++) { + unmovableIDs[i] = -1; + needUnmountingIDs[i] = -1; + } + } + // get the info + bool result = _kern_supports_moving_partition(_ShadowID(), unmovableIDs, + needUnmountingIDs, descendantCount); + if (result) { + // find unmovable BPartition objects for returned IDs + for (int32 i = 0; i < descendantCount && unmovableIDs[i] != -1; i++) { + BPartition *descendant = FindDescendant(unmovableIDs[i]); + if (!descendant || !unmovableDescendants->AddItem(descendant)) + return false; + } + // find BPartition objects needing to be unmounted for returned IDs + for (int32 i = 0; i < descendantCount && needUnmountingIDs[i] != -1; + i++) { + BPartition *descendant = FindDescendant(needUnmountingIDs[i]); + if (!descendant || !movableOnlyIfUnmounted->AddItem(descendant)) + return false; } } - // cleanup and return - delete[] descendants; return result; }