From 96418817f9b399c87e54db708fcc45dd3d327637 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sat, 2 Feb 2008 12:38:15 +0000 Subject: [PATCH] * added a PrintToStream() method * added optional tracing for the main operations * fixed bad pointer arithmetic when reallocating/moving the object's data * it was impossible to remove the very first space via _RemoveSpaces() * added a little more variaty to error return codes for some functions to make them a little more helpful -> This fixes the bogus space values in DriveSetup (#1737) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23824 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/storage/PartitioningInfo.h | 1 + .../storage/disk_device/PartitioningInfo.cpp | 74 +++++++++++++++++-- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/headers/private/storage/PartitioningInfo.h b/headers/private/storage/PartitioningInfo.h index 479a5297ca..906012061b 100644 --- a/headers/private/storage/PartitioningInfo.h +++ b/headers/private/storage/PartitioningInfo.h @@ -28,6 +28,7 @@ public: off_t* offset, off_t*size) const; int32 CountPartitionableSpaces() const; + void PrintToStream() const; private: status_t _InsertSpaces(int32 index, int32 count); void _RemoveSpaces(int32 index, int32 count); diff --git a/src/kits/storage/disk_device/PartitioningInfo.cpp b/src/kits/storage/disk_device/PartitioningInfo.cpp index b0fcc51ea1..cae1859ed5 100644 --- a/src/kits/storage/disk_device/PartitioningInfo.cpp +++ b/src/kits/storage/disk_device/PartitioningInfo.cpp @@ -3,6 +3,7 @@ // by the OpenBeOS license. //--------------------------------------------------------------------- +#include #include #include @@ -16,6 +17,14 @@ using namespace std; +//#define TRACING 1 +#if TRACING +# define TRACE(x) printf x +#else +# define TRACE(x) +#endif + + // constructor BPartitioningInfo::BPartitioningInfo() : fPartitionID(-1), @@ -37,6 +46,8 @@ BPartitioningInfo::~BPartitioningInfo() status_t BPartitioningInfo::SetTo(off_t offset, off_t size) { + TRACE(("%p - BPartitioningInfo::SetTo(offset = %lld, size = %lld)\n", this, offset, size)); + fPartitionID = -1; delete[] fSpaces; @@ -78,6 +89,9 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) if (size <= 0) return B_OK; + TRACE(("%p - BPartitioningInfo::ExcludeOccupiedSpace(offset = %lld, " + "size = %lld)\n", this, offset, size)); + int32 leftIndex = -1; int32 rightIndex = -1; for (int32 i = 0; i < fCount; i++) { @@ -90,6 +104,8 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) rightIndex = i; } + TRACE((" leftIndex = %ld, rightIndex = %ld\n", leftIndex, rightIndex)); + // If there's no intersection with any free space, we're done. if (leftIndex == -1 || rightIndex == -1 || leftIndex > rightIndex) return B_OK; @@ -102,11 +118,18 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) // special case: split a single space in two if (leftIndex == rightIndex && leftSpace.offset < offset && rightSpaceEnd > offset + size) { + + TRACE((" splitting space at %ld\n", leftIndex)); + // add a space after this one status_t error = _InsertSpaces(leftIndex + 1, 1); if (error != B_OK) return error; + // IMPORTANT: after calling _InsertSpace(), one can not + // use the partitionable_space_data references "leftSpace" + // and "rightSpace" anymore (declared above)! + partitionable_space_data& space = fSpaces[leftIndex]; partitionable_space_data& newSpace = fSpaces[leftIndex + 1]; @@ -115,6 +138,9 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) newSpace.offset = offset + size; newSpace.size = rightSpaceEnd - newSpace.offset; + #ifdef TRACING + PrintToStream(); + #endif return B_OK; } @@ -122,6 +148,9 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) int32 deleteFirst = leftIndex; if (leftSpace.offset < offset) { leftSpace.size = offset - leftSpace.offset; + + TRACE((" left space remains, new size is %lld\n", leftSpace.size)); + deleteFirst++; } @@ -130,6 +159,10 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) if (rightSpaceEnd > offset + size) { rightSpace.offset = offset + size; rightSpace.size = rightSpaceEnd - rightSpace.offset; + + TRACE((" right space remains, new offset = %lld, size = %lld\n", + rightSpace.offset, rightSpace.size)); + deleteLast--; } @@ -137,6 +170,9 @@ BPartitioningInfo::ExcludeOccupiedSpace(off_t offset, off_t size) if (deleteFirst <= deleteLast) _RemoveSpaces(deleteFirst, deleteLast - deleteFirst + 1); + #ifdef TRACING + PrintToStream(); + #endif return B_OK; } @@ -154,8 +190,12 @@ status_t BPartitioningInfo::GetPartitionableSpaceAt(int32 index, off_t *offset, off_t *size) const { - if (!fSpaces || !offset || !size || index < 0 || index >= fCount) + if (!fSpaces) + return B_NO_INIT; + if (!offset || !size) return B_BAD_VALUE; + if (index < 0 || index >= fCount) + return B_BAD_INDEX; *offset = fSpaces[index].offset; *size = fSpaces[index].size; return B_OK; @@ -170,6 +210,25 @@ BPartitioningInfo::CountPartitionableSpaces() const } +// PrintToStream +void +BPartitioningInfo::PrintToStream() const +{ + if (!fSpaces) { + printf("BPartitioningInfo is not initialized\n"); + return; + } + printf("BPartitioningInfo has %ld spaces:\n", fCount); + for (int32 i = 0; i < fCount; i++) { + printf(" space at %ld: offset = %lld, size = %lld\n", + i, fSpaces[i].offset, fSpaces[i].size); + } +} + + +// #pragma mark - + + // _InsertSpaces status_t BPartitioningInfo::_InsertSpaces(int32 index, int32 count) @@ -180,7 +239,8 @@ BPartitioningInfo::_InsertSpaces(int32 index, int32 count) // If the capacity is sufficient, we just need to copy the spaces to create // a gap. if (fCount + count <= fCapacity) { - memmove(fSpaces + index + count, fSpaces + index, fCount - index); + memmove(fSpaces + index + count, fSpaces + index, + (fCount - index) * sizeof(partitionable_space_data)); fCount += count; return B_OK; } @@ -195,8 +255,9 @@ BPartitioningInfo::_InsertSpaces(int32 index, int32 count) return B_NO_MEMORY; // copy items - memcpy(spaces, fSpaces, index); - memcpy(spaces + index + count, fSpaces + index, fCount - index); + memcpy(spaces, fSpaces, index * sizeof(partitionable_space_data)); + memcpy(spaces + index + count, fSpaces + index, + (fCount - index) * sizeof(partitionable_space_data)); delete[] fSpaces; fSpaces = spaces; @@ -211,12 +272,13 @@ BPartitioningInfo::_InsertSpaces(int32 index, int32 count) void BPartitioningInfo::_RemoveSpaces(int32 index, int32 count) { - if (index <= 0 || count <= 0 || index + count > fCount) + if (index < 0 || count <= 0 || index + count > fCount) return; if (count < fCount) { int32 endIndex = index + count; - memmove(fSpaces + index, fSpaces + endIndex, fCount - endIndex); + memmove(fSpaces + index, fSpaces + endIndex, + (fCount - endIndex) * sizeof(partitionable_space_data)); } fCount -= count;