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
This commit is contained in:
Ingo Weinhold 2003-07-21 14:17:33 +00:00
parent c0b8ba64fd
commit d61adbe244
2 changed files with 64 additions and 24 deletions

View File

@ -81,7 +81,7 @@ public:
status_t Resize(off_t size, bool resizeContents = true); status_t Resize(off_t size, bool resizeContents = true);
bool CanMove(BObjectList<BPartition> *unmovableDescendants, bool CanMove(BObjectList<BPartition> *unmovableDescendants,
bool *whileMounted = NULL) const; BObjectList<BPartition> *movableOnlyIfUnmounted) const;
status_t ValidateMove(off_t *newOffset, bool force = false) const; status_t ValidateMove(off_t *newOffset, bool force = false) const;
status_t Move(off_t newOffset, bool force = false); status_t Move(off_t newOffset, bool force = false);

View File

@ -27,6 +27,33 @@
(\see IsEmpty()). (\see IsEmpty()).
*/ */
// AutoDeleter
/*! \brief Helper class deleting objects automatically.
*/
template<typename C>
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 // constructor
BPartition::BPartition() BPartition::BPartition()
: fDevice(NULL), : fDevice(NULL),
@ -479,38 +506,51 @@ BPartition::Resize(off_t size, bool resizeContents)
// CanMove // CanMove
bool bool
BPartition::CanMove(BObjectList<BPartition> *unmovableDescendants, BPartition::CanMove(BObjectList<BPartition> *unmovableDescendants,
bool *whileMounted) const BObjectList<BPartition> *movableOnlyIfUnmounted) const
{ {
// check parameters // check parameters
if (!unmovableDescendants || !fPartitionData || IsDevice() || !Parent() if (!unmovableDescendants || !movableOnlyIfUnmounted || !fPartitionData
|| !_IsShadow()) { || IsDevice() || !Parent() || !_IsShadow()) {
return false; return false;
} }
// count descendants and allocate a partition_id array large enough // count descendants and allocate partition_id arrays large enough
int32 descendantCount = _CountDescendants(); int32 descendantCount = _CountDescendants();
partition_id *descendants = NULL; partition_id *unmovableIDs = NULL;
partition_id *needUnmountingIDs = NULL;
AutoDeleter<partition_id> deleter1;
AutoDeleter<partition_id> deleter2;
if (descendantCount > 0) { if (descendantCount > 0) {
descendants = new(nothrow) partition_id[descendantCount]; // allocate arrays
if (!descendants) 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; return false;
for (int32 i = 0; i < descendantCount; i++) // init arrays
descendants[i] = -1; for (int32 i = 0; i < descendantCount; i++) {
} unmovableIDs[i] = -1;
// get the info needUnmountingIDs[i] = -1;
bool result = _kern_supports_moving_partition(_ShadowID(), descendants, }
descendantCount, whileMounted); }
if (result) { // get the info
// find BPartition objects for returned IDs bool result = _kern_supports_moving_partition(_ShadowID(), unmovableIDs,
for (int32 i = 0; i < descendantCount && descendants[i] != -1; i++) { needUnmountingIDs, descendantCount);
BPartition *descendant = FindDescendant(descendants[i]); if (result) {
if (!descendant || !unmovableDescendants->AddItem(descendant)) { // find unmovable BPartition objects for returned IDs
result = false; for (int32 i = 0; i < descendantCount && unmovableIDs[i] != -1; i++) {
break; 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; return result;
} }