From f7769aa482ea0c807ad71b94a06eeef3335af86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 23 May 2006 01:24:38 +0000 Subject: [PATCH] Some more PPC big endian fixes, mostly array handling (b+tree duplicates and log). Still doesn't seem to work correctly, though (but it's definitely getting closer :-)). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17560 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/bfs/r5/BPlusTree.cpp | 54 +++++++++---------- .../kernel/file_systems/bfs/r5/Journal.cpp | 26 ++++----- .../kernel/file_systems/bfs/r5/Utility.cpp | 34 ++++++------ .../kernel/file_systems/bfs/r5/Utility.h | 24 +++++---- .../kernel/file_systems/bfs/r5/Volume.cpp | 2 +- 5 files changed, 71 insertions(+), 69 deletions(-) diff --git a/src/tests/add-ons/kernel/file_systems/bfs/r5/BPlusTree.cpp b/src/tests/add-ons/kernel/file_systems/bfs/r5/BPlusTree.cpp index 439c36fa99..3054f9eacc 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/r5/BPlusTree.cpp +++ b/src/tests/add-ons/kernel/file_systems/bfs/r5/BPlusTree.cpp @@ -676,16 +676,16 @@ BPlusTree::InsertDuplicate(Transaction *transaction, CachedNode *cached, bplustr return B_IO_ERROR; duplicate_array *array = duplicate->FragmentAt(bplustree_node::FragmentIndex(oldValue)); - if (array->count > NUM_FRAGMENT_VALUES - || array->count < 1) { + if (array->CountItems() > NUM_FRAGMENT_VALUES + || array->CountItems() < 1) { FATAL(("insertDuplicate: Invalid array[%ld] size in fragment %Ld == %Ld!\n", bplustree_node::FragmentIndex(oldValue), bplustree_node::FragmentOffset(oldValue), - array->count)); + array->CountItems())); return B_BAD_DATA; } - if (array->count < NUM_FRAGMENT_VALUES) { + if (array->CountItems() < NUM_FRAGMENT_VALUES) { array->Insert(value); } else { // test if the fragment will be empty if we remove this key's values @@ -710,9 +710,9 @@ BPlusTree::InsertDuplicate(Transaction *transaction, CachedNode *cached, bplustr // copy the array from the fragment node to the duplicate node // and free the old entry (by zero'ing all values) - newDuplicate->overflow_link = HOST_ENDIAN_TO_BFS_INT64(array->count); + newDuplicate->overflow_link = array->count; memcpy(&newDuplicate->all_key_count, &array->values[0], - array->count * sizeof(off_t)); + array->CountItems() * sizeof(off_t)); memset(array, 0, (NUM_FRAGMENT_VALUES + 1) * sizeof(off_t)); array = newDuplicate->DuplicateArray(); @@ -748,15 +748,15 @@ BPlusTree::InsertDuplicate(Transaction *transaction, CachedNode *cached, bplustr return B_IO_ERROR; array = duplicate->DuplicateArray(); - if (array->count > NUM_DUPLICATE_VALUES || array->count < 0) { + if (array->CountItems() > NUM_DUPLICATE_VALUES || array->CountItems() < 0) { FATAL(("removeDuplicate: Invalid array size in duplicate %Ld == %Ld!\n", - duplicateOffset, array->count)); + duplicateOffset, array->CountItems())); return B_BAD_DATA; } - } while (array->count >= NUM_DUPLICATE_VALUES + } while (array->CountItems() >= NUM_DUPLICATE_VALUES && (oldValue = duplicate->RightLink()) != BPLUSTREE_NULL); - if (array->count < NUM_DUPLICATE_VALUES) { + if (array->CountItems() < NUM_DUPLICATE_VALUES) { array->Insert(value); } else { // no space left - add a new duplicate node @@ -770,11 +770,11 @@ BPlusTree::InsertDuplicate(Transaction *transaction, CachedNode *cached, bplustr // link the two nodes together duplicate->right_link = HOST_ENDIAN_TO_BFS_INT64(offset); newDuplicate->left_link = HOST_ENDIAN_TO_BFS_INT64(duplicateOffset); - + array = newDuplicate->DuplicateArray(); array->count = 0; array->Insert(value); - + status = cachedNewDuplicate.WriteBack(transaction); if (status < B_OK) return status; @@ -1214,10 +1214,10 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache if (bplustree_node::LinkType(oldValue) == BPLUSTREE_DUPLICATE_FRAGMENT) { duplicate_array *array = duplicate->FragmentAt(bplustree_node::FragmentIndex(oldValue)); - if (array->count > NUM_FRAGMENT_VALUES - || array->count < 1) { + if (array->CountItems() > NUM_FRAGMENT_VALUES + || array->CountItems() < 1) { FATAL(("removeDuplicate: Invalid array[%ld] size in fragment %Ld == %Ld!\n", - bplustree_node::FragmentIndex(oldValue), duplicateOffset, array->count)); + bplustree_node::FragmentIndex(oldValue), duplicateOffset, array->CountItems())); return B_BAD_DATA; } if (!array->Remove(value)) { @@ -1227,7 +1227,7 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache } // remove the array from the fragment node if it is empty - if (array->count == 1) { + if (array->CountItems() == 1) { // set the link to the remaining value values[index] = array->values[0]; @@ -1259,10 +1259,10 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache // Search the duplicate nodes until the entry could be found (and removed) while (duplicate != NULL) { array = duplicate->DuplicateArray(); - if (array->count > NUM_DUPLICATE_VALUES - || array->count < 0) { + if (array->CountItems() > NUM_DUPLICATE_VALUES + || array->CountItems() < 0) { FATAL(("removeDuplicate: Invalid array size in duplicate %Ld == %Ld!\n", - duplicateOffset, array->count)); + duplicateOffset, array->CountItems())); return B_BAD_DATA; } @@ -1281,15 +1281,15 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache off_t left = duplicate->LeftLink(); off_t right = duplicate->RightLink(); bool isLast = left == BPLUSTREE_NULL && right == BPLUSTREE_NULL; - - if (isLast && array->count == 1 || array->count == 0) { + + if (isLast && array->CountItems() == 1 || array->CountItems() == 0) { // Free empty duplicate page, link their siblings together, and // update the duplicate link if needed (which should not be, if // we are the only one working on that tree...) if (duplicateOffset == bplustree_node::FragmentOffset(oldValue) - || array->count == 1) { - if (array->count == 1 && isLast) + || array->CountItems() == 1) { + if (array->CountItems() == 1 && isLast) values[index] = array->values[0]; else if (isLast) { FATAL(("removed last value from duplicate!\n")); @@ -1297,7 +1297,7 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache values[index] = HOST_ENDIAN_TO_BFS_INT64(bplustree_node::MakeLink( BPLUSTREE_DUPLICATE_NODE, right)); } - + if ((status = cached->WriteBack(transaction)) < B_OK) return status; } @@ -1329,7 +1329,7 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache // Again, we may need to turn the duplicate entry back into a normal entry array = duplicate->DuplicateArray(); if (left == BPLUSTREE_NULL && duplicate->RightLink() == BPLUSTREE_NULL - && duplicate->DuplicateArray()->count <= NUM_FRAGMENT_VALUES) { + && duplicate->DuplicateArray()->CountItems() <= NUM_FRAGMENT_VALUES) { duplicateOffset = right; continue; } @@ -1337,7 +1337,7 @@ BPlusTree::RemoveDuplicate(Transaction *transaction, bplustree_node *node, Cache return cachedDuplicate.WriteBack(transaction); } return status; - } else if (isLast && array->count <= NUM_FRAGMENT_VALUES) { + } else if (isLast && array->CountItems() <= NUM_FRAGMENT_VALUES) { // If the number of entries fits in a duplicate fragment, then // either find a free fragment node, or convert this node to a // fragment node. @@ -2023,7 +2023,7 @@ bplustree_node::FragmentsUsed(uint32 nodeSize) uint32 used = 0; for (uint32 i = 0; i < nodeSize / ((NUM_FRAGMENT_VALUES + 1) * sizeof(off_t)); i++) { duplicate_array *array = FragmentAt(i); - if (array->count > 0 && ++used > 1) + if (array->CountItems() > 0 && ++used > 1) return used; } return used; diff --git a/src/tests/add-ons/kernel/file_systems/bfs/r5/Journal.cpp b/src/tests/add-ons/kernel/file_systems/bfs/r5/Journal.cpp index d152f62c28..d984f1084f 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/r5/Journal.cpp +++ b/src/tests/add-ons/kernel/file_systems/bfs/r5/Journal.cpp @@ -121,7 +121,7 @@ Journal::Journal(Volume *volume) fLock("bfs journal"), fOwner(NULL), fArray(volume->BlockSize()), - fLogSize(volume->Log().length), + fLogSize(volume->Log().Length()), fMaxTransactionSize(fLogSize / 4 - 5), fUsed(0), fTransactionsInEntry(0) @@ -259,9 +259,9 @@ Journal::ReplayLog() } PRINT(("replaying worked fine!\n")); - fVolume->SuperBlock().log_start = fVolume->LogEnd(); + fVolume->SuperBlock().log_start = HOST_ENDIAN_TO_BFS_INT64(fVolume->LogEnd()); fVolume->LogStart() = fVolume->LogEnd(); - fVolume->SuperBlock().flags = SUPER_BLOCK_DISK_CLEAN; + fVolume->SuperBlock().flags = HOST_ENDIAN_TO_BFS_INT32(SUPER_BLOCK_DISK_CLEAN); return fVolume->WriteSuperBlock(); } @@ -295,9 +295,9 @@ Journal::blockNotify(off_t blockNumber, size_t numBlocks, void *arg) LogEntry *next = journal->fEntries.GetNext(logEntry); if (next != NULL) { int32 length = next->Start() - logEntry->Start(); - superBlock.log_start = (superBlock.log_start + length) % journal->fLogSize; + superBlock.log_start = HOST_ENDIAN_TO_BFS_INT64((superBlock.LogStart() + length) % journal->fLogSize); } else - superBlock.log_start = journal->fVolume->LogEnd(); + superBlock.log_start = HOST_ENDIAN_TO_BFS_INT64(journal->fVolume->LogEnd()); update = true; } @@ -354,7 +354,7 @@ Journal::WriteLogEntry() LogEntry *logEntry = NULL, *firstEntry = NULL, *lastAdded = NULL; - for (int32 i = 0; i < array->count; i++) { + for (int32 i = 0; i < array->CountItems(); i++) { retry: if (logEntry == NULL) { logEntry = new LogEntry(this, logStart); @@ -370,7 +370,7 @@ Journal::WriteLogEntry() logStart++; } - if (!logEntry->InsertBlock(array->values[i])) { + if (!logEntry->InsertBlock(array->ValueAt(i))) { // log entry is full - start a new one fEntriesLock.Lock(); fEntries.Add(logEntry); @@ -410,7 +410,7 @@ Journal::WriteLogEntry() if (block == NULL) return B_IO_ERROR; - // write blocks + // write blocks write_pos(fVolume->Device(), logOffset + (logPosition << blockShift), block, fVolume->BlockSize()); @@ -420,11 +420,11 @@ Journal::WriteLogEntry() fEntriesLock.Unlock(); - fUsed += array->count; + fUsed += array->CountItems(); // Update the log end pointer in the super block - fVolume->SuperBlock().flags = SUPER_BLOCK_DISK_DIRTY; - fVolume->SuperBlock().log_end = logPosition; + fVolume->SuperBlock().flags = HOST_ENDIAN_TO_BFS_INT32(SUPER_BLOCK_DISK_DIRTY); + fVolume->SuperBlock().log_end = HOST_ENDIAN_TO_BFS_INT64(logPosition); fVolume->LogEnd() = logPosition; status_t status = fVolume->WriteSuperBlock(); @@ -543,8 +543,8 @@ Journal::TransactionDone(bool success) if (array != NULL) { // release the lock for all blocks in the array (we don't need // to be notified when they are actually written to disk) - for (int32 i = 0; i < array->count; i++) - release_block(fVolume->Device(), array->values[i]); + for (int32 i = 0; i < array->CountItems(); i++) + release_block(fVolume->Device(), array->ValueAt(i)); } return B_OK; diff --git a/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.cpp b/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.cpp index b05f568c5f..59ae90b9eb 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.cpp +++ b/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.cpp @@ -1,6 +1,6 @@ /* Utility - some helper classes * - * Copyright 2001-2005, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2006, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ @@ -15,14 +15,14 @@ bool -sorted_array::FindInternal(off_t value, int32 &index) const +sorted_array::_FindInternal(off_t value, int32 &index) const { - int32 min = 0, max = count-1; + int32 min = 0, max = CountItems() - 1; off_t cmp; while (min <= max) { index = (min + max) / 2; - cmp = values[index] - value; + cmp = ValueAt(index) - value; if (cmp < 0) min = index + 1; else if (cmp > 0) @@ -41,19 +41,19 @@ sorted_array::Insert(off_t value) // binary search, if not, just iterate linearly to find // the insertion point int32 i; - if (count > 8 ) { - if (!FindInternal(value,i) - && values[i] <= value) + if (CountItems() > 8 ) { + if (!_FindInternal(value, i) && ValueAt(i) <= value) i++; } else { - for (i = 0;i < count; i++) - if (values[i] > value) + for (i = 0; i < CountItems(); i++) { + if (ValueAt(i) > value) break; + } } - memmove(&values[i+1],&values[i],(count - i) * sizeof(off_t)); - values[i] = value; - count++; + memmove(&values[i + 1], &values[i], (CountItems() - i) * sizeof(off_t)); + values[i] = HOST_ENDIAN_TO_BFS_INT64(value); + count = HOST_ENDIAN_TO_BFS_INT64(CountItems() + 1); } @@ -64,8 +64,8 @@ sorted_array::Remove(off_t value) if (index == -1) return false; - memmove(&values[index],&values[index + 1],(count - index) * sizeof(off_t)); - count--; + memmove(&values[index], &values[index + 1], (CountItems() - index) * sizeof(off_t)); + count = HOST_ENDIAN_TO_BFS_INT64(CountItems() - 1); return true; } @@ -103,11 +103,11 @@ BlockArray::Find(off_t value) status_t BlockArray::Insert(off_t value) { - if (fArray == NULL || fArray->count + 1 > fMaxBlocks) { - sorted_array *array = (sorted_array *)realloc(fArray,fSize + fBlockSize); + if (fArray == NULL || fArray->CountItems() + 1 > fMaxBlocks) { + sorted_array *array = (sorted_array *)realloc(fArray, fSize + fBlockSize); if (array == NULL) return B_NO_MEMORY; - + if (fArray == NULL) array->count = 0; diff --git a/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.h b/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.h index ef6e5df7e5..21d3614297 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.h +++ b/src/tests/add-ons/kernel/file_systems/bfs/r5/Utility.h @@ -1,13 +1,13 @@ /* Utility - some helper classes * - * Copyright 2001-2005, Axel Dörfler, axeld@pinc-software.de + * Copyright 2001-2006, Axel Dörfler, axeld@pinc-software.de * This file may be used under the terms of the MIT License. */ #ifndef UTILITY_H #define UTILITY_H -#include +#include "bfs_endian.h" // Simple array, used for the duplicate handling in the B+Tree, @@ -17,18 +17,20 @@ struct sorted_array { public: off_t count; - #if __MWERKS__ - off_t values[1]; - #else - off_t values[0]; - #endif +#if __MWERKS__ + off_t values[1]; +#else + off_t values[0]; +#endif + off_t CountItems() const { return BFS_ENDIAN_TO_HOST_INT64(count); } + off_t ValueAt(int32 index) const { return BFS_ENDIAN_TO_HOST_INT64(values[index]); } inline int32 Find(off_t value) const; void Insert(off_t value); bool Remove(off_t value); private: - bool FindInternal(off_t value,int32 &index) const; + bool _FindInternal(off_t value, int32 &index) const; }; @@ -36,7 +38,7 @@ inline int32 sorted_array::Find(off_t value) const { int32 i; - return FindInternal(value,i) ? i : -1; + return _FindInternal(value, i) ? i : -1; } @@ -56,8 +58,8 @@ class BlockArray { void MakeEmpty(); - int32 CountItems() const { return fArray != NULL ? fArray->count : 0; } - int32 BlocksUsed() const { return fArray != NULL ? ((fArray->count + 1) * sizeof(off_t) + fBlockSize - 1) / fBlockSize : 0; } + int32 CountItems() const { return fArray != NULL ? fArray->CountItems() : 0; } + int32 BlocksUsed() const { return fArray != NULL ? ((fArray->CountItems() + 1) * sizeof(off_t) + fBlockSize - 1) / fBlockSize : 0; } sorted_array *Array() const { return fArray; } int32 Size() const { return fSize; } diff --git a/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp b/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp index e661d767ea..0205c87016 100644 --- a/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp +++ b/src/tests/add-ons/kernel/file_systems/bfs/r5/Volume.cpp @@ -596,7 +596,7 @@ Volume::Initialize(const char *device, const char *name, uint32 blockSize, uint3 // cannot use BlockAllocator::BitmapSize() here fSuperBlock.log_blocks = ToBlockRun(AllocationGroups() * fSuperBlock.BlocksPerAllocationGroup() + 1); - fSuperBlock.log_blocks.length = 2048; + fSuperBlock.log_blocks.length = HOST_ENDIAN_TO_BFS_INT16(2048); // ToDo: set the log size depending on the disk size fSuperBlock.log_start = fSuperBlock.log_end = HOST_ENDIAN_TO_BFS_INT64(ToBlock(Log()));