hrev43906 adds 6 changesets to branch 'master' old head: 948be77f8785af8f5506ebe1a4fb7d78c6e05fcb new head: 1674a53a45f12befa208e7478337d811d1fed6fd ---------------------------------------------------------------------------- 17f6950: No need for 'else' after return. fd8b9d4: Added a recursive_lock_transfer() function. b81ce43: Made fLock a recursive lock instead of a mutex. * This should fix bug #8069. aed54a9: Use ID() instead of BlockNumber() for the debug output. 225e1b1: Minor cleanup. 1674a53: Added recursive_lock_transfer_lock() to the fs_shell. [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 8 files changed, 157 insertions(+), 133 deletions(-) headers/private/fs_shell/fssh_api_wrapper.h | 1 + headers/private/fs_shell/fssh_lock.h | 1 + headers/private/kernel/lock.h | 14 + src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp | 42 ++-- .../kernel/file_systems/bfs/BlockAllocator.cpp | 202 ++++++++-------- .../kernel/file_systems/bfs/BlockAllocator.h | 5 +- src/add-ons/kernel/file_systems/bfs/Index.h | 12 +- src/tools/fs_shell/lock.cpp | 13 +- ############################################################################ Commit: 17f695029a2fde258db98322c12786e730a7e0e4 URL: http://cgit.haiku-os.org/haiku/commit/?id=17f6950 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Mar 30 14:21:23 2012 UTC No need for 'else' after return. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 540cfae..35184df 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -1475,98 +1475,99 @@ BlockAllocator::CheckNextNode(check_control* control) // TODO: maybe have a force parameter that actually does that. // TODO: we also need to be able to repair broken B+trees! return status; - } else { - // ignore "." and ".." entries - if (!strcmp(name, ".") || !strcmp(name, "..")) - continue; + } - // fill in the control data as soon as we have them - strlcpy(fCheckCookie->control.name, name, B_FILE_NAME_LENGTH); - fCheckCookie->control.inode = id; - fCheckCookie->control.errors = 0; + // ignore "." and ".." entries + if (!strcmp(name, ".") || !strcmp(name, "..")) + continue; - Vnode vnode(fVolume, id); - Inode* inode; - if (vnode.Get(&inode) != B_OK) { - FATAL(("Could not open inode ID %" B_PRIdINO "!\n", id)); - fCheckCookie->control.errors |= BFS_COULD_NOT_OPEN; + // fill in the control data as soon as we have them + strlcpy(fCheckCookie->control.name, name, B_FILE_NAME_LENGTH); + fCheckCookie->control.inode = id; + fCheckCookie->control.errors = 0; - if ((fCheckCookie->control.flags & BFS_REMOVE_INVALID) != 0) { - status = _RemoveInvalidNode(fCheckCookie->parent, - fCheckCookie->iterator->Tree(), NULL, name); - } else - status = B_ERROR; + Vnode vnode(fVolume, id); + Inode* inode; + if (vnode.Get(&inode) != B_OK) { + FATAL(("Could not open inode ID %" B_PRIdINO "!\n", id)); + fCheckCookie->control.errors |= BFS_COULD_NOT_OPEN; - fCheckCookie->control.status = status; - return B_OK; - } + if ((fCheckCookie->control.flags & BFS_REMOVE_INVALID) != 0) { + status = _RemoveInvalidNode(fCheckCookie->parent, + fCheckCookie->iterator->Tree(), NULL, name); + } else + status = B_ERROR; - // check if the inode's name is the same as in the b+tree - if (inode->IsRegularNode()) { - RecursiveLocker locker(inode->SmallDataLock()); - NodeGetter node(fVolume, inode); - - const char* localName = inode->Name(node.Node()); - if (localName == NULL || strcmp(localName, name)) { - fCheckCookie->control.errors |= BFS_NAMES_DONT_MATCH; - FATAL(("Names differ: tree \"%s\", inode \"%s\"\n", name, - localName)); - - if ((fCheckCookie->control.flags & BFS_FIX_NAME_MISMATCHES) - != 0) { - // Rename the inode - Transaction transaction(fVolume, inode->BlockNumber()); - - status = inode->SetName(transaction, name); - if (status == B_OK) - status = inode->WriteBack(transaction); - if (status == B_OK) - status = transaction.Done(); - if (status != B_OK) { - fCheckCookie->control.status = status; - return B_OK; - } + fCheckCookie->control.status = status; + return B_OK; + } + + // check if the inode's name is the same as in the b+tree + if (inode->IsRegularNode()) { + RecursiveLocker locker(inode->SmallDataLock()); + NodeGetter node(fVolume, inode); + + const char* localName = inode->Name(node.Node()); + if (localName == NULL || strcmp(localName, name)) { + fCheckCookie->control.errors |= BFS_NAMES_DONT_MATCH; + FATAL(("Names differ: tree \"%s\", inode \"%s\"\n", name, + localName)); + + if ((fCheckCookie->control.flags & BFS_FIX_NAME_MISMATCHES) + != 0) { + // Rename the inode + Transaction transaction(fVolume, inode->BlockNumber()); + + // TODO: this may potentially need new blocks! + status = inode->SetName(transaction, name); + if (status == B_OK) + status = inode->WriteBack(transaction); + if (status == B_OK) + status = transaction.Done(); + if (status != B_OK) { + fCheckCookie->control.status = status; + return B_OK; } } } + } - fCheckCookie->control.mode = inode->Mode(); - - // Check for the correct mode of the node (if the mode of the - // file don't fit to its parent, there is a serious problem) - if (((fCheckCookie->parent_mode & S_ATTR_DIR) != 0 - && !inode->IsAttribute()) - || ((fCheckCookie->parent_mode & S_INDEX_DIR) != 0 - && !inode->IsIndex()) - || (is_directory(fCheckCookie->parent_mode) - && !inode->IsRegularNode())) { - FATAL(("inode at %" B_PRIdOFF " is of wrong type: %o (parent " - "%o at %" B_PRIdOFF ")!\n", inode->BlockNumber(), - inode->Mode(), fCheckCookie->parent_mode, - fCheckCookie->parent->BlockNumber())); - - // if we are allowed to fix errors, we should remove the file - if ((fCheckCookie->control.flags & BFS_REMOVE_WRONG_TYPES) != 0 - && (fCheckCookie->control.flags & BFS_FIX_BITMAP_ERRORS) - != 0) { - status = _RemoveInvalidNode(fCheckCookie->parent, NULL, - inode, name); - } else - status = B_ERROR; - - fCheckCookie->control.errors |= BFS_WRONG_TYPE; - fCheckCookie->control.status = status; - return B_OK; - } + fCheckCookie->control.mode = inode->Mode(); + + // Check for the correct mode of the node (if the mode of the + // file don't fit to its parent, there is a serious problem) + if (((fCheckCookie->parent_mode & S_ATTR_DIR) != 0 + && !inode->IsAttribute()) + || ((fCheckCookie->parent_mode & S_INDEX_DIR) != 0 + && !inode->IsIndex()) + || (is_directory(fCheckCookie->parent_mode) + && !inode->IsRegularNode())) { + FATAL(("inode at %" B_PRIdOFF " is of wrong type: %o (parent " + "%o at %" B_PRIdOFF ")!\n", inode->BlockNumber(), + inode->Mode(), fCheckCookie->parent_mode, + fCheckCookie->parent->BlockNumber())); + + // if we are allowed to fix errors, we should remove the file + if ((fCheckCookie->control.flags & BFS_REMOVE_WRONG_TYPES) != 0 + && (fCheckCookie->control.flags & BFS_FIX_BITMAP_ERRORS) + != 0) { + status = _RemoveInvalidNode(fCheckCookie->parent, NULL, + inode, name); + } else + status = B_ERROR; + + fCheckCookie->control.errors |= BFS_WRONG_TYPE; + fCheckCookie->control.status = status; + return B_OK; + } - // push the directory on the stack so that it will be scanned later - if (inode->IsContainer() && !inode->IsIndex()) - fCheckCookie->stack.Push(inode->BlockRun()); - else { - // check it now - fCheckCookie->control.status = CheckInode(inode); - return B_OK; - } + // push the directory on the stack so that it will be scanned later + if (inode->IsContainer() && !inode->IsIndex()) + fCheckCookie->stack.Push(inode->BlockRun()); + else { + // check it now + fCheckCookie->control.status = CheckInode(inode); + return B_OK; } } // is never reached ############################################################################ Commit: fd8b9d4326f093222e23e2a33f53b0d03857443a URL: http://cgit.haiku-os.org/haiku/commit/?id=fd8b9d4 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Mar 30 15:05:19 2012 UTC Added a recursive_lock_transfer() function. ---------------------------------------------------------------------------- diff --git a/headers/private/kernel/lock.h b/headers/private/kernel/lock.h index 4381d21..2a52c44 100644 --- a/headers/private/kernel/lock.h +++ b/headers/private/kernel/lock.h @@ -274,6 +274,20 @@ mutex_transfer_lock(mutex* lock, thread_id thread) } +static inline void +recursive_lock_transfer_lock(recursive_lock* lock, thread_id thread) +{ + if (lock->recursion != 1) + panic("invalid recursion level for lock transfer!"); + +#if KDEBUG + lock->lock.holder = thread; +#else + lock->holder = thread; +#endif +} + + extern void lock_debug_init(); #ifdef __cplusplus ############################################################################ Commit: b81ce43017cf63b0de3ff056200a323c56ebdf86 URL: http://cgit.haiku-os.org/haiku/commit/?id=b81ce43 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Mar 30 15:06:10 2012 UTC Ticket: https://dev.haiku-os.org/ticket/8069 Made fLock a recursive lock instead of a mutex. * This should fix bug #8069. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index 35184df..2769f6f 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -520,13 +520,13 @@ BlockAllocator::BlockAllocator(Volume* volume) fCheckBitmap(NULL), fCheckCookie(NULL) { - mutex_init(&fLock, "bfs allocator"); + recursive_lock_init(&fLock, "bfs allocator"); } BlockAllocator::~BlockAllocator() { - mutex_destroy(&fLock); + recursive_lock_destroy(&fLock); delete[] fGroups; } @@ -546,7 +546,7 @@ BlockAllocator::Initialize(bool full) if (!full) return B_OK; - mutex_lock(&fLock); + recursive_lock_lock(&fLock); // the lock will be released by the _Initialize() method thread_id id = spawn_kernel_thread((thread_func)BlockAllocator::_Initialize, @@ -554,7 +554,7 @@ BlockAllocator::Initialize(bool full) if (id < B_OK) return _Initialize(this); - mutex_transfer_lock(&fLock, id); + recursive_lock_transfer_lock(&fLock, id); return resume_thread(id); } @@ -624,6 +624,7 @@ status_t BlockAllocator::_Initialize(BlockAllocator* allocator) { // The lock must already be held at this point + RecursiveLocker locker(allocator->fLock, true); Volume* volume = allocator->fVolume; uint32 blocks = allocator->fBlocksPerGroup; @@ -631,10 +632,8 @@ BlockAllocator::_Initialize(BlockAllocator* allocator) off_t freeBlocks = 0; uint32* buffer = (uint32*)malloc(blocks << blockShift); - if (buffer == NULL) { - mutex_unlock(&allocator->fLock); + if (buffer == NULL) RETURN_ERROR(B_NO_MEMORY); - } AllocationGroup* groups = allocator->fGroups; off_t offset = 1; @@ -715,7 +714,6 @@ BlockAllocator::_Initialize(BlockAllocator* allocator) volume->SuperBlock().used_blocks = HOST_ENDIAN_TO_BFS_INT64(usedBlocks); } - mutex_unlock(&allocator->fLock); return B_OK; } @@ -725,7 +723,7 @@ BlockAllocator::Uninitialize() { // We only have to make sure that the initializer thread isn't running // anymore. - mutex_lock(&fLock); + recursive_lock_lock(&fLock); } @@ -747,7 +745,7 @@ BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex, groupIndex, start, maximum, minimum)); AllocationBlock cached(fVolume); - MutexLocker lock(fLock); + RecursiveLocker lock(fLock); uint32 bitsPerFullBlock = fVolume->BlockSize() << 3; @@ -1005,7 +1003,7 @@ BlockAllocator::Allocate(Transaction& transaction, Inode* inode, status_t BlockAllocator::Free(Transaction& transaction, block_run run) { - MutexLocker lock(fLock); + RecursiveLocker lock(fLock); int32 group = run.AllocationGroup(); uint16 start = run.Start(); @@ -1072,7 +1070,7 @@ void BlockAllocator::Fragment() { AllocationBlock cached(fVolume); - MutexLocker lock(fLock); + RecursiveLocker lock(fLock); // only leave 4 block holes static const uint32 kMask = 0x0f0f0f0f; @@ -1103,7 +1101,7 @@ void BlockAllocator::_CheckGroup(int32 groupIndex) const { AllocationBlock cached(fVolume); - ASSERT_LOCKED_MUTEX(&fLock); + ASSERT_LOCKED_RECURSIVE(&fLock); AllocationGroup& group = fGroups[groupIndex]; @@ -1202,16 +1200,12 @@ BlockAllocator::StartChecking(const check_control* control) fVolume->GetJournal(0)->Lock(NULL, true); // Lock the volume's journal - status_t status = mutex_lock(&fLock); - if (status != B_OK) { - fVolume->GetJournal(0)->Unlock(NULL, true); - return status; - } + recursive_lock_lock(&fLock); size_t size = BitmapSize(); fCheckBitmap = (uint32*)malloc(size); if (fCheckBitmap == NULL) { - mutex_unlock(&fLock); + recursive_lock_unlock(&fLock); fVolume->GetJournal(0)->Unlock(NULL, true); return B_NO_MEMORY; } @@ -1220,7 +1214,7 @@ BlockAllocator::StartChecking(const check_control* control) if (fCheckCookie == NULL) { free(fCheckBitmap); fCheckBitmap = NULL; - mutex_unlock(&fLock); + recursive_lock_unlock(&fLock); fVolume->GetJournal(0)->Unlock(NULL, true); return B_NO_MEMORY; @@ -1354,7 +1348,7 @@ BlockAllocator::StopChecking(check_control* control) fCheckBitmap = NULL; delete fCheckCookie; fCheckCookie = NULL; - mutex_unlock(&fLock); + recursive_lock_unlock(&fLock); fVolume->GetJournal(0)->Unlock(NULL, true); return B_OK; @@ -1518,7 +1512,8 @@ BlockAllocator::CheckNextNode(check_control* control) // Rename the inode Transaction transaction(fVolume, inode->BlockNumber()); - // TODO: this may potentially need new blocks! + // Note, this may need extra blocks, but the inode will + // only be checked afterwards, so that it won't be lost status = inode->SetName(transaction, name); if (status == B_OK) status = inode->WriteBack(transaction); diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h index aaddf94..5e6bf2b 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2010, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2001-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * This file may be used under the terms of the MIT License. */ #ifndef BLOCK_ALLOCATOR_H @@ -78,8 +78,9 @@ private: static status_t _Initialize(BlockAllocator* self); +private: Volume* fVolume; - mutex fLock; + recursive_lock fLock; AllocationGroup* fGroups; int32 fNumGroups; uint32 fBlocksPerGroup; ############################################################################ Commit: aed54a9a464b24a96df17fb349a46c171e362f47 URL: http://cgit.haiku-os.org/haiku/commit/?id=aed54a9 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Mar 30 18:55:24 2012 UTC Use ID() instead of BlockNumber() for the debug output. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index d31274d..92dd8da 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -708,7 +708,7 @@ BPlusTree::Validate(bool repair, bool& _errorsFound) if (check.Visited(freeOffset)) { dprintf("inode %" B_PRIdOFF ": free node at %" B_PRIdOFF - " circular!\n", fStream->BlockNumber(), freeOffset); + " circular!\n", fStream->ID(), freeOffset); break; } @@ -716,7 +716,7 @@ BPlusTree::Validate(bool repair, bool& _errorsFound) if (node->OverflowLink() != BPLUSTREE_FREE) { dprintf("inode %" B_PRIdOFF ": free node at %" B_PRIdOFF - " misses free mark!\n", fStream->BlockNumber(), freeOffset); + " misses free mark!\n", fStream->ID(), freeOffset); } freeOffset = node->LeftLink(); } @@ -738,14 +738,14 @@ BPlusTree::Validate(bool repair, bool& _errorsFound) if (check.MaxLevels() + 1 != fHeader.MaxNumberOfLevels()) { dprintf("inode %" B_PRIdOFF ": found %" B_PRIu32 " max levels, " - "declared %" B_PRIu32 "!\n", fStream->BlockNumber(), - check.MaxLevels(), fHeader.MaxNumberOfLevels()); + "declared %" B_PRIu32 "!\n", fStream->ID(), check.MaxLevels(), + fHeader.MaxNumberOfLevels()); } if (check.VisitedCount() != fHeader.MaximumSize() / fNodeSize) { dprintf("inode %" B_PRIdOFF ": visited %" B_PRIuSIZE " from %" B_PRIdOFF - " nodes.\n", fStream->BlockNumber(), - check.VisitedCount(), fHeader.MaximumSize() / fNodeSize); + " nodes.\n", fStream->ID(), check.VisitedCount(), + fHeader.MaximumSize() / fNodeSize); } return B_OK; @@ -2177,13 +2177,13 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, { if (parent->CheckIntegrity(fNodeSize) != B_OK) { dprintf("inode %" B_PRIdOFF ": node %" B_PRIdOFF " integrity check " - "failed!\n", fStream->BlockNumber(), offset); + "failed!\n", fStream->ID(), offset); check.FoundError(); return B_OK; } if (level >= fHeader.MaxNumberOfLevels()) { dprintf("inode %" B_PRIdOFF ": maximum level surpassed at %" B_PRIdOFF - "!\n", fStream->BlockNumber(), offset); + "!\n", fStream->ID(), offset); check.FoundError(); return B_OK; } @@ -2192,7 +2192,7 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, if (check.Visited(offset)) { dprintf("inode %" B_PRIdOFF ": node %" B_PRIdOFF " already visited!\n", - fStream->BlockNumber(), offset); + fStream->ID(), offset); check.FoundError(); return B_OK; } @@ -2213,7 +2213,7 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, if (result >= 0) { dprintf("inode %" B_PRIdOFF ": node %" B_PRIdOFF " key %" B_PRIu32 " larger than it should!\n", - fStream->BlockNumber(), offset, i); + fStream->ID(), offset, i); check.FoundError(); } } @@ -2237,7 +2237,7 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, if (!isKnownFragment && check.Visited(duplicateOffset)) { dprintf("inode %" B_PRIdOFF ": duplicate node at %" - B_PRIdOFF " already visited!\n", fStream->BlockNumber(), + B_PRIdOFF " already visited!\n", fStream->ID(), duplicateOffset); check.FoundError(); break; @@ -2265,7 +2265,7 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, if (arrayCount < 1 || arrayCount > maxSize) { dprintf("inode %" B_PRIdOFF ": duplicate at %" B_PRIdOFF " has invalid array size %" B_PRId32 "!\n", - fStream->BlockNumber(), duplicateOffset, arrayCount); + fStream->ID(), duplicateOffset, arrayCount); check.FoundError(); } else { // Simple check if the values in the array may be valid @@ -2274,7 +2274,7 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, array->ValueAt(j))) { dprintf("inode %" B_PRIdOFF ": duplicate at %" B_PRIdOFF " contains invalid block %" B_PRIdOFF - " at %" B_PRId32 "!\n", fStream->BlockNumber(), + " at %" B_PRId32 "!\n", fStream->ID(), duplicateOffset, array->ValueAt(j), j); check.FoundError(); break; @@ -2289,8 +2289,8 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, if (node->LeftLink() != lastDuplicateOffset) { dprintf("inode %" B_PRIdOFF ": duplicate at %" B_PRIdOFF " has wrong left link %" B_PRIdOFF ", expected %" - B_PRIdOFF "!\n", fStream->BlockNumber(), - duplicateOffset, node->LeftLink(), lastDuplicateOffset); + B_PRIdOFF "!\n", fStream->ID(), duplicateOffset, + node->LeftLink(), lastDuplicateOffset); check.FoundError(); } @@ -2312,8 +2312,8 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, if (previous->RightLink() != childOffset) { dprintf("inode %" B_PRIdOFF ": node at %" B_PRIdOFF " has " "wrong right link %" B_PRIdOFF ", expected %" B_PRIdOFF - "!\n", fStream->BlockNumber(), lastOffset, - previous->RightLink(), childOffset); + "!\n", fStream->ID(), lastOffset, previous->RightLink(), + childOffset); check.FoundError(); } } @@ -2325,7 +2325,7 @@ BPlusTree::_ValidateChildren(TreeCheck& check, uint32 level, off_t offset, } else if (!fStream->GetVolume()->IsValidInodeBlock(childOffset)) { dprintf("inode %" B_PRIdOFF ": node at %" B_PRIdOFF " contains " "invalid block %" B_PRIdOFF " at %" B_PRId32 "!\n", - fStream->BlockNumber(), offset, childOffset, i); + fStream->ID(), offset, childOffset, i); check.FoundError(); } @@ -2359,16 +2359,14 @@ BPlusTree::_ValidateChild(TreeCheck& check, CachedNode& cached, uint32 level, if (node->LeftLink() != lastOffset) { dprintf("inode %" B_PRIdOFF ": node at %" B_PRIdOFF " has " "wrong left link %" B_PRIdOFF ", expected %" B_PRIdOFF - "!\n", fStream->BlockNumber(), offset, node->LeftLink(), - lastOffset); + "!\n", fStream->ID(), offset, node->LeftLink(), lastOffset); check.FoundError(); } if (nextOffset != 0 && node->RightLink() != nextOffset) { dprintf("inode %" B_PRIdOFF ": node at %" B_PRIdOFF " has " "wrong right link %" B_PRIdOFF ", expected %" B_PRIdOFF - "!\n", fStream->BlockNumber(), offset, node->RightLink(), - nextOffset); + "!\n", fStream->ID(), offset, node->RightLink(), nextOffset); check.FoundError(); } ############################################################################ Commit: 225e1b11906b0aa0f4feb4d1ca0605fab4da6c4b URL: http://cgit.haiku-os.org/haiku/commit/?id=225e1b1 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Mar 30 18:56:38 2012 UTC Minor cleanup. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/bfs/Index.h b/src/add-ons/kernel/file_systems/bfs/Index.h index ae63dfb..5825548 100644 --- a/src/add-ons/kernel/file_systems/bfs/Index.h +++ b/src/add-ons/kernel/file_systems/bfs/Index.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx + * Copyright 2001-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx * This file may be used under the terms of the MIT License. */ #ifndef INDEX_H @@ -18,17 +18,17 @@ class Index { public: Index(Volume* volume); ~Index(); - + status_t SetTo(const char* name); void Unset(); Inode* Node() const { return fNode; }; uint32 Type(); size_t KeySize(); - + status_t Create(Transaction& transaction, const char* name, uint32 type); - + status_t Update(Transaction& transaction, const char* name, int32 type, const uint8* oldKey, uint16 oldLength, const uint8* newKey, @@ -45,7 +45,7 @@ public: status_t InsertSize(Transaction& transaction, Inode* inode); status_t RemoveSize(Transaction& transaction, Inode* inode); status_t UpdateSize(Transaction& transaction, Inode* inode); - + status_t InsertLastModified(Transaction& transaction, Inode* inode); status_t RemoveLastModified(Transaction& transaction, @@ -58,9 +58,11 @@ private: Index& operator=(const Index& other); // no implementation +private: Volume* fVolume; Inode* fNode; const char* fName; }; + #endif // INDEX_H ############################################################################ Revision: hrev43906 Commit: 1674a53a45f12befa208e7478337d811d1fed6fd URL: http://cgit.haiku-os.org/haiku/commit/?id=1674a53 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Fri Mar 30 20:04:34 2012 UTC Added recursive_lock_transfer_lock() to the fs_shell. ---------------------------------------------------------------------------- diff --git a/headers/private/fs_shell/fssh_api_wrapper.h b/headers/private/fs_shell/fssh_api_wrapper.h index 18fb61b..edb40a9 100644 --- a/headers/private/fs_shell/fssh_api_wrapper.h +++ b/headers/private/fs_shell/fssh_api_wrapper.h @@ -1013,6 +1013,7 @@ #define recursive_lock_trylock fssh_recursive_lock_trylock #define recursive_lock_unlock fssh_recursive_lock_unlock #define recursive_lock_get_recursion fssh_recursive_lock_get_recursion +#define recursive_lock_transfer_lock fssh_recursive_lock_transfer_lock #define rw_lock_init fssh_rw_lock_init #define rw_lock_init_etc fssh_rw_lock_init_etc diff --git a/headers/private/fs_shell/fssh_lock.h b/headers/private/fs_shell/fssh_lock.h index 8be96a1..23f246b 100644 --- a/headers/private/fs_shell/fssh_lock.h +++ b/headers/private/fs_shell/fssh_lock.h @@ -61,6 +61,7 @@ extern fssh_status_t fssh_recursive_lock_lock(fssh_recursive_lock *lock); extern fssh_status_t fssh_recursive_lock_trylock(fssh_recursive_lock *lock); extern void fssh_recursive_lock_unlock(fssh_recursive_lock *lock); extern int32_t fssh_recursive_lock_get_recursion(fssh_recursive_lock *lock); +extern void fssh_recursive_lock_transfer_lock(fssh_recursive_lock *lock, fssh_thread_id thread); extern void fssh_rw_lock_init(fssh_rw_lock* lock, const char* name); // name is *not* cloned nor freed in rw_lock_destroy() diff --git a/src/tools/fs_shell/lock.cpp b/src/tools/fs_shell/lock.cpp index 8b8ae72..5008c77 100644 --- a/src/tools/fs_shell/lock.cpp +++ b/src/tools/fs_shell/lock.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights reserved. + * Copyright 2002-2012, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights reserved. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -102,6 +102,17 @@ fssh_recursive_lock_unlock(fssh_recursive_lock *lock) } +extern "C" void +fssh_recursive_lock_transfer_lock(fssh_recursive_lock *lock, + fssh_thread_id thread) +{ + if (lock->recursion != 1) + fssh_panic("invalid recursion level for lock transfer!"); + + lock->holder = thread; +} + + // #pragma mark -