diff --git a/src/add-ons/disk_systems/bfs/Jamfile b/src/add-ons/disk_systems/bfs/Jamfile index ff74f2f064..1850fe136b 100644 --- a/src/add-ons/disk_systems/bfs/Jamfile +++ b/src/add-ons/disk_systems/bfs/Jamfile @@ -1,8 +1,7 @@ SubDir HAIKU_TOP src add-ons disk_systems bfs ; -UsePrivateHeaders kernel ; -UsePrivateHeaders shared ; -UsePrivateHeaders storage ; +UsePrivateKernelHeaders ; +UsePrivateHeaders shared storage ; SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems bfs ] ; diff --git a/src/add-ons/kernel/file_systems/bfs/Attribute.cpp b/src/add-ons/kernel/file_systems/bfs/Attribute.cpp index 69b35da011..ab43fe9a42 100644 --- a/src/add-ons/kernel/file_systems/bfs/Attribute.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Attribute.cpp @@ -79,13 +79,13 @@ Attribute::Get(const char *name) fName = name; // try to find it in the small data region - if (fInode->SmallDataLock().Lock() == B_OK) { + if (recursive_lock_lock(&fInode->SmallDataLock()) == B_OK) { fNodeGetter.SetToNode(fInode); fSmall = fInode->FindSmallData(fNodeGetter.Node(), (const char *)name); if (fSmall != NULL) return B_OK; - fInode->SmallDataLock().Unlock(); + recursive_lock_unlock(&fInode->SmallDataLock()); fNodeGetter.Unset(); } @@ -98,7 +98,7 @@ void Attribute::Put() { if (fSmall != NULL) { - fInode->SmallDataLock().Unlock(); + recursive_lock_unlock(&fInode->SmallDataLock()); fNodeGetter.Unset(); fSmall = NULL; } @@ -195,7 +195,7 @@ Attribute::Read(attr_cookie *cookie, off_t pos, uint8 *buffer, size_t *_length) if (fSmall == NULL && fAttribute == NULL) return B_NO_INIT; - // ToDo: move small_data logic from Inode::ReadAttribute() over to here! + // TODO: move small_data logic from Inode::ReadAttribute() over to here! return fInode->ReadAttribute(cookie->name, 0, pos, buffer, _length); } diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp index f33c375ae3..00d1a4c5c3 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.cpp @@ -341,6 +341,7 @@ BPlusTree::BPlusTree(Transaction &transaction, Inode *stream, int32 nodeSize) fHeader(NULL), fCachedHeader(this) { + mutex_init(&fIteratorLock, "bfs b+tree iterator"); SetTo(transaction, stream); } @@ -351,6 +352,7 @@ BPlusTree::BPlusTree(Inode *stream) fHeader(NULL), fCachedHeader(this) { + mutex_init(&fIteratorLock, "bfs b+tree iterator"); SetTo(stream); } @@ -364,6 +366,7 @@ BPlusTree::BPlusTree() fAllowDuplicates(true), fStatus(B_NO_INIT) { + mutex_init(&fIteratorLock, "bfs b+tree iterator"); } @@ -372,14 +375,13 @@ BPlusTree::~BPlusTree() // if there are any TreeIterators left, we need to stop them // (can happen when the tree's inode gets deleted while // traversing the tree - a TreeIterator doesn't lock the inode) - if (fIteratorLock.Lock() < B_OK) - return; + mutex_lock(&fIteratorLock); TreeIterator *iterator = NULL; while ((iterator = fIterators.Next(iterator)) != NULL) iterator->Stop(); - fIteratorLock.Unlock(); + mutex_destroy(&fIteratorLock); } @@ -565,38 +567,27 @@ BPlusTree::_UpdateIterators(off_t offset, off_t nextOffset, uint16 keyIndex, // Although every iterator which is affected by this update currently // waits on a semaphore, other iterators could be added/removed at // any time, so we need to protect this loop - if (fIteratorLock.Lock() < B_OK) - return; + MutexLocker _(fIteratorLock); TreeIterator *iterator = NULL; while ((iterator = fIterators.Next(iterator)) != NULL) iterator->Update(offset, nextOffset, keyIndex, splitAt, change); - - fIteratorLock.Unlock(); } void BPlusTree::_AddIterator(TreeIterator *iterator) { - if (fIteratorLock.Lock() < B_OK) - return; - + MutexLocker _(fIteratorLock); fIterators.Add(iterator); - - fIteratorLock.Unlock(); } void BPlusTree::_RemoveIterator(TreeIterator *iterator) { - if (fIteratorLock.Lock() < B_OK) - return; - + MutexLocker _(fIteratorLock); fIterators.Remove(iterator); - - fIteratorLock.Unlock(); } @@ -2139,7 +2130,8 @@ TreeIterator::SkipDuplicates() void -TreeIterator::Update(off_t offset, off_t nextOffset, uint16 keyIndex, uint16 splitAt, int8 change) +TreeIterator::Update(off_t offset, off_t nextOffset, uint16 keyIndex, + uint16 splitAt, int8 change) { if (offset != fCurrentNodeOffset) return; @@ -2158,7 +2150,7 @@ TreeIterator::Update(off_t offset, off_t nextOffset, uint16 keyIndex, uint16 spl if (keyIndex <= fCurrentKey) fCurrentKey += change; - // ToDo: duplicate handling! + // TODO: duplicate handling! } diff --git a/src/add-ons/kernel/file_systems/bfs/BPlusTree.h b/src/add-ons/kernel/file_systems/bfs/BPlusTree.h index aa56f0a9b7..bb2c5d5688 100644 --- a/src/add-ons/kernel/file_systems/bfs/BPlusTree.h +++ b/src/add-ons/kernel/file_systems/bfs/BPlusTree.h @@ -273,7 +273,7 @@ class BPlusTree { int32 fNodeSize; bool fAllowDuplicates; status_t fStatus; - SimpleLock fIteratorLock; + mutex fIteratorLock; Chain fIterators; }; diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp index ea4d6ab25a..cdabf3d726 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.cpp @@ -441,15 +441,16 @@ AllocationGroup::Free(Transaction &transaction, uint16 start, int32 length) BlockAllocator::BlockAllocator(Volume *volume) : fVolume(volume), - fLock("bfs allocator"), fGroups(NULL), fCheckBitmap(NULL) { + mutex_init(&fLock, "bfs allocator"); } BlockAllocator::~BlockAllocator() { + mutex_destroy(&fLock); delete[] fGroups; } @@ -457,9 +458,6 @@ BlockAllocator::~BlockAllocator() status_t BlockAllocator::Initialize(bool full) { - if (fLock.InitCheck() < B_OK) - return B_ERROR; - fNumGroups = fVolume->AllocationGroups(); fBlocksPerGroup = fVolume->SuperBlock().BlocksPerAllocationGroup(); fGroups = new AllocationGroup[fNumGroups]; @@ -469,8 +467,8 @@ BlockAllocator::Initialize(bool full) if (!full) return B_OK; - fLock.Lock(); - // the lock will be released by the initialize() function + mutex_lock(&fLock); + // the lock will be released by the _Initialize() method thread_id id = spawn_kernel_thread((thread_func)BlockAllocator::_Initialize, "bfs block allocator", B_LOW_PRIORITY, (void *)this); @@ -547,7 +545,7 @@ BlockAllocator::_Initialize(BlockAllocator *allocator) uint32 *buffer = (uint32 *)malloc(blocks << blockShift); if (buffer == NULL) { - allocator->fLock.Unlock(); + mutex_unlock(&allocator->fLock); RETURN_ERROR(B_NO_MEMORY); } @@ -621,7 +619,7 @@ BlockAllocator::_Initialize(BlockAllocator *allocator) volume->SuperBlock().used_blocks = HOST_ENDIAN_TO_BFS_INT64(usedBlocks); } - allocator->fLock.Unlock(); + mutex_unlock(&allocator->fLock); return B_OK; } @@ -636,7 +634,7 @@ BlockAllocator::AllocateBlocks(Transaction &transaction, int32 group, FUNCTION_START(("group = %ld, start = %u, maximum = %u, minimum = %u\n", group, start, maximum, minimum)); AllocationBlock cached(fVolume); - Locker lock(fLock); + MutexLocker lock(fLock); // The first scan through all allocation groups will look for the // wanted maximum of blocks, the second scan will just look to @@ -821,7 +819,7 @@ BlockAllocator::Allocate(Transaction &transaction, Inode *inode, off_t numBlocks status_t BlockAllocator::Free(Transaction &transaction, block_run run) { - Locker lock(fLock); + MutexLocker lock(fLock); int32 group = run.AllocationGroup(); uint16 start = run.Start(); @@ -896,14 +894,14 @@ BlockAllocator::StartChecking(check_control *control) if (!_IsValidCheckControl(control)) return B_BAD_VALUE; - status_t status = fLock.Lock(); + status_t status = mutex_lock(&fLock); if (status < B_OK) return status; size_t size = BitmapSize(); fCheckBitmap = (uint32 *)malloc(size); if (fCheckBitmap == NULL) { - fLock.Unlock(); + mutex_unlock(&fLock); return B_NO_MEMORY; } @@ -911,7 +909,7 @@ BlockAllocator::StartChecking(check_control *control) if (cookie == NULL) { free(fCheckBitmap); fCheckBitmap = NULL; - fLock.Unlock(); + mutex_unlock(&fLock); return B_NO_MEMORY; } @@ -1013,7 +1011,7 @@ BlockAllocator::StopChecking(check_control *control) fCheckBitmap = NULL; fCheckCookie = NULL; delete cookie; - fLock.Unlock(); + mutex_unlock(&fLock); return B_OK; } @@ -1113,7 +1111,7 @@ BlockAllocator::CheckNextNode(check_control *control) // check if the inode's name is the same as in the b+tree if (inode->IsRegularNode()) { - SimpleLocker locker(inode->SmallDataLock()); + RecursiveLocker locker(inode->SmallDataLock()); NodeGetter node(fVolume, inode); const char *localName = inode->Name(node.Node()); diff --git a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h index 4a5d152be4..21fad7792c 100644 --- a/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h +++ b/src/add-ons/kernel/file_systems/bfs/BlockAllocator.h @@ -6,7 +6,7 @@ #define BLOCK_ALLOCATOR_H -#include "Lock.h" +#include "system_dependencies.h" class AllocationGroup; @@ -57,7 +57,7 @@ class BlockAllocator { static status_t _Initialize(BlockAllocator *); Volume *fVolume; - Semaphore fLock; + mutex fLock; AllocationGroup *fGroups; int32 fNumGroups; uint32 fBlocksPerGroup; diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 2c6ca76f90..86ace7dc99 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -330,6 +330,8 @@ Inode::Inode(Volume *volume, ino_t id) (int)BlockRun().AllocationGroup(), BlockRun().Start()); fLock.Initialize(lockName); + recursive_lock_init(&fSmallDataLock, "bfs inode small data"); + // these two will help to maintain the indices fOldSize = Size(); fOldLastModified = LastModified(); @@ -361,6 +363,8 @@ Inode::Inode(Volume *volume, Transaction &transaction, ino_t id, mode_t mode, (int)run.AllocationGroup(), run.Start()); fLock.Initialize(lockName); + recursive_lock_init(&fSmallDataLock, "bfs inode small data"); + NodeGetter node(volume, transaction, this, true); memset(&fNode, 0, sizeof(bfs_inode)); @@ -482,24 +486,16 @@ Inode::CheckPermissions(int accessMode) const void Inode::_AddIterator(AttributeIterator *iterator) { - if (fSmallDataLock.Lock() < B_OK) - return; - + RecursiveLocker _(fSmallDataLock); fIterators.Add(iterator); - - fSmallDataLock.Unlock(); } void Inode::_RemoveIterator(AttributeIterator *iterator) { - if (fSmallDataLock.Lock() < B_OK) - return; - + RecursiveLocker _(fSmallDataLock); fIterators.Remove(iterator); - - fSmallDataLock.Unlock(); } @@ -511,7 +507,7 @@ status_t Inode::_MakeSpaceForSmallData(Transaction &transaction, bfs_inode *node, const char *name, int32 bytes) { - ASSERT(fSmallDataLock.IsLocked()); + ASSERT_LOCKED_RECURSIVE(&fSmallDataLock); while (bytes > 0) { small_data *item = node->SmallDataStart(), *max = NULL; @@ -575,7 +571,7 @@ Inode::_MakeSpaceForSmallData(Transaction &transaction, bfs_inode *node, status_t Inode::_RemoveSmallData(bfs_inode *node, small_data *item, int32 index) { - ASSERT(fSmallDataLock.IsLocked()); + ASSERT_LOCKED_RECURSIVE(&fSmallDataLock); small_data *next = item->Next(); if (!next->IsLast(node)) { @@ -617,7 +613,7 @@ Inode::_RemoveSmallData(Transaction &transaction, NodeGetter &nodeGetter, return B_BAD_VALUE; bfs_inode *node = nodeGetter.WritableNode(); - SimpleLocker locker(fSmallDataLock); + RecursiveLocker locker(fSmallDataLock); // search for the small_data item @@ -668,7 +664,7 @@ Inode::_AddSmallData(Transaction &transaction, NodeGetter &nodeGetter, return B_DEVICE_FULL; nodeGetter.MakeWritable(transaction); - SimpleLocker locker(fSmallDataLock); + RecursiveLocker locker(fSmallDataLock); // Find the last item or one with the same name we have to add small_data *item = node->SmallDataStart(); @@ -809,7 +805,7 @@ Inode::_GetNextSmallData(bfs_inode *node, small_data **_smallData) const if (node == NULL) RETURN_ERROR(B_BAD_VALUE); - ASSERT(fSmallDataLock.IsLocked()); + ASSERT_LOCKED_RECURSIVE(&fSmallDataLock); small_data *data = *_smallData; @@ -836,7 +832,7 @@ Inode::_GetNextSmallData(bfs_inode *node, small_data **_smallData) const small_data * Inode::FindSmallData(const bfs_inode *node, const char *name) const { - ASSERT(fSmallDataLock.IsLocked()); + ASSERT_LOCKED_RECURSIVE(&fSmallDataLock); small_data *smallData = NULL; while (_GetNextSmallData(const_cast(node), &smallData) @@ -855,7 +851,7 @@ Inode::FindSmallData(const bfs_inode *node, const char *name) const const char * Inode::Name(const bfs_inode *node) const { - ASSERT(fSmallDataLock.IsLocked()); + ASSERT_LOCKED_RECURSIVE(&fSmallDataLock); small_data *smallData = NULL; while (_GetNextSmallData((bfs_inode *)node, &smallData) == B_OK) { @@ -874,7 +870,7 @@ status_t Inode::GetName(char *buffer, size_t size) const { NodeGetter node(fVolume, this); - SimpleLocker locker(fSmallDataLock); + RecursiveLocker locker(fSmallDataLock); const char *name = Name(node.Node()); if (name == NULL) @@ -966,7 +962,7 @@ Inode::ReadAttribute(const char *name, int32 type, off_t pos, uint8 *buffer, // search in the small_data section (which has to be locked first) { NodeGetter node(fVolume, this); - SimpleLocker locker(fSmallDataLock); + RecursiveLocker locker(fSmallDataLock); small_data *smallData = FindSmallData(node.Node(), name); if (smallData != NULL) { @@ -1025,7 +1021,7 @@ Inode::WriteAttribute(Transaction &transaction, const char *name, int32 type, if (GetAttribute(name, &attribute) < B_OK) { // save the old attribute data NodeGetter node(fVolume, transaction, this); - fSmallDataLock.Lock(); + recursive_lock_lock(&fSmallDataLock); small_data *smallData = FindSmallData(node.Node(), name); if (smallData != NULL) { @@ -1036,7 +1032,7 @@ Inode::WriteAttribute(Transaction &transaction, const char *name, int32 type, memcpy(oldData = oldBuffer, smallData->Data(), oldLength); } } - fSmallDataLock.Unlock(); + recursive_lock_unlock(&fSmallDataLock); // if the attribute doesn't exist yet (as a file), try to put it in the // small_data section first - if that fails (due to insufficent space), @@ -1128,7 +1124,7 @@ Inode::RemoveAttribute(Transaction &transaction, const char *name) // update index for attributes in the small_data section { - fSmallDataLock.Lock(); + RecursiveLocker _(fSmallDataLock); small_data *smallData = FindSmallData(node.Node(), name); if (smallData != NULL) { @@ -1138,7 +1134,6 @@ Inode::RemoveAttribute(Transaction &transaction, const char *name) index.Update(transaction, name, smallData->Type(), smallData->Data(), length, NULL, 0, this); } - fSmallDataLock.Unlock(); } status_t status = _RemoveSmallData(transaction, node, name); @@ -2561,7 +2556,7 @@ AttributeIterator::GetNext(char *name, size_t *_length, uint32 *_type, const bfs_inode *node = nodeGetter.Node(); const small_data *item = ((bfs_inode *)node)->SmallDataStart(); - fInode->SmallDataLock().Lock(); + RecursiveLocker _(&fInode->SmallDataLock()); int32 i = 0; for (;;item = item->Next()) { @@ -2589,8 +2584,6 @@ AttributeIterator::GetNext(char *name, size_t *_length, uint32 *_type, fCurrentSmallData = -1; } - fInode->SmallDataLock().Unlock(); - if (fCurrentSmallData != -1) return B_OK; } diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index a9a07f90e9..fcccd93624 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -46,7 +46,7 @@ class Inode { off_t BlockNumber() const { return fVolume->VnodeToBlock(fID); } ReadWriteLock &Lock() { return fLock; } - SimpleLock &SmallDataLock() { return fSmallDataLock; } + recursive_lock &SmallDataLock() { return fSmallDataLock; } status_t WriteBack(Transaction &transaction); bool IsContainer() const @@ -207,7 +207,7 @@ class Inode { // we need those values to ensure we will remove // the correct keys from the indices - mutable SimpleLock fSmallDataLock; + mutable recursive_lock fSmallDataLock; Chain fIterators; }; diff --git a/src/add-ons/kernel/file_systems/bfs/Jamfile b/src/add-ons/kernel/file_systems/bfs/Jamfile index 8782a56a18..f594463c9f 100644 --- a/src/add-ons/kernel/file_systems/bfs/Jamfile +++ b/src/add-ons/kernel/file_systems/bfs/Jamfile @@ -24,10 +24,9 @@ SubDir HAIKU_TOP src add-ons kernel file_systems bfs ; SubDirC++Flags $(defines) -Wall -Wno-multichar ; } -UsePrivateHeaders [ FDirName kernel ] ; # For kernel_cpp.cpp +UsePrivateKernelHeaders ; UsePrivateHeaders [ FDirName kernel disk_device_manager ] ; -UsePrivateHeaders [ FDirName shared ] ; -UsePrivateHeaders [ FDirName storage ] ; +UsePrivateHeaders shared storage ; KernelAddon bfs : bfs_disk_system.cpp diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index d9e183e250..dea9915251 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -395,7 +395,6 @@ RunArrays::MaxArrayLength() Journal::Journal(Volume *volume) : fVolume(volume), - fLock("bfs journal"), fOwner(NULL), fLogSize(volume->Log().Length()), fMaxTransactionSize(fLogSize / 2 - 5), @@ -403,19 +402,24 @@ Journal::Journal(Volume *volume) fUnwrittenTransactions(0), fHasSubtransaction(false) { + recursive_lock_init(&fLock, "bfs journal"); + mutex_init(&fEntriesLock, "bfs journal entries"); } Journal::~Journal() { FlushLogAndBlocks(); + + recursive_lock_destroy(&fLock); + mutex_destroy(&fEntriesLock); } status_t Journal::InitCheck() { - return fLock.InitCheck(); + return B_OK; } @@ -605,7 +609,7 @@ Journal::_TransactionWritten(int32 transactionID, int32 event, void *_logEntry) // Set log_start pointer if possible... - journal->fEntriesLock.Lock(); + mutex_lock(&journal->fEntriesLock); if (logEntry == journal->fEntries.First()) { LogEntry *next = journal->fEntries.GetNext(logEntry); @@ -624,7 +628,7 @@ Journal::_TransactionWritten(int32 transactionID, int32 event, void *_logEntry) journal->fUsed -= logEntry->Length(); journal->fEntries.Remove(logEntry); - journal->fEntriesLock.Unlock(); + mutex_unlock(&journal->fEntriesLock); delete logEntry; @@ -839,10 +843,10 @@ Journal::_WriteTransactionToLog() // at this point, we can finally end the transaction - we're in // a guaranteed valid state - fEntriesLock.Lock(); + mutex_lock(&fEntriesLock); fEntries.Add(logEntry); fUsed += logEntry->Length(); - fEntriesLock.Unlock(); + mutex_unlock(&fEntriesLock); if (detached) { fTransactionID = cache_detach_sub_transaction(fVolume->BlockCache(), @@ -864,13 +868,14 @@ Journal::_WriteTransactionToLog() status_t Journal::_FlushLog(bool canWait, bool flushBlocks) { - status_t status = canWait ? fLock.Lock() : fLock.LockWithTimeout(0); + status_t status = canWait ? recursive_lock_lock(&fLock) + : recursive_lock_trylock(&fLock); if (status != B_OK) return status; - if (fLock.OwnerCount() > 1) { + if (recursive_lock_get_recursion(&fLock) > 1) { // whoa, FlushLogAndBlocks() was called from inside a transaction - fLock.Unlock(); + recursive_lock_unlock(&fLock); return B_OK; } @@ -885,7 +890,7 @@ Journal::_FlushLog(bool canWait, bool flushBlocks) if (flushBlocks) status = fVolume->FlushDevice(); - fLock.Unlock(); + recursive_lock_unlock(&fLock); return status; } @@ -903,11 +908,11 @@ Journal::FlushLogAndBlocks() status_t Journal::Lock(Transaction *owner) { - status_t status = fLock.Lock(); + status_t status = recursive_lock_lock(&fLock); if (status != B_OK) return status; - if (fLock.OwnerCount() > 1) { + if (recursive_lock_get_recursion(&fLock) > 1) { // we'll just use the current transaction again return B_OK; } @@ -929,7 +934,7 @@ Journal::Lock(Transaction *owner) fTransactionID = cache_start_transaction(fVolume->BlockCache()); if (fTransactionID < B_OK) { - fLock.Unlock(); + recursive_lock_unlock(&fLock); return fTransactionID; } @@ -943,7 +948,7 @@ Journal::Lock(Transaction *owner) void Journal::Unlock(Transaction *owner, bool success) { - if (fLock.OwnerCount() == 1) { + if (recursive_lock_get_recursion(&fLock) == 1) { // we only end the transaction if we would really unlock it // ToDo: what about failing transactions that do not unlock? _TransactionDone(success); @@ -952,7 +957,7 @@ Journal::Unlock(Transaction *owner, bool success) fOwner = NULL; } - fLock.Unlock(); + recursive_lock_unlock(&fLock); } diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.h b/src/add-ons/kernel/file_systems/bfs/Journal.h index d6857d6243..d72ac15eec 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.h +++ b/src/add-ons/kernel/file_systems/bfs/Journal.h @@ -14,6 +14,7 @@ #include "Volume.h" #include "Chain.h" +#include "Lock.h" #include "Utility.h" @@ -69,11 +70,11 @@ class Journal { void *_journal); Volume *fVolume; - RecursiveLock fLock; + recursive_lock fLock; Transaction *fOwner; uint32 fLogSize, fMaxTransactionSize, fUsed; int32 fUnwrittenTransactions; - SimpleLock fEntriesLock; + mutex fEntriesLock; LogEntryList fEntries; bigtime_t fTimestamp; int32 fTransactionID; diff --git a/src/add-ons/kernel/file_systems/bfs/Lock.h b/src/add-ons/kernel/file_systems/bfs/Lock.h index 23880741cf..2c02e71ad0 100644 --- a/src/add-ons/kernel/file_systems/bfs/Lock.h +++ b/src/add-ons/kernel/file_systems/bfs/Lock.h @@ -26,201 +26,7 @@ # error implement recursive write locking first #endif -class Semaphore { - public: - Semaphore(const char *name) - : -#ifdef USE_BENAPHORE - fSemaphore(create_sem(0, name)), - fCount(1) -#else - fSemaphore(create_sem(1, name)) -#endif - { - } - - ~Semaphore() - { - delete_sem(fSemaphore); - } - - status_t InitCheck() - { - if (fSemaphore < B_OK) - return fSemaphore; - - return B_OK; - } - - status_t Lock() - { -#ifdef USE_BENAPHORE - if (atomic_add(&fCount, -1) <= 0) -#endif - return acquire_sem(fSemaphore); -#ifdef USE_BENAPHORE - return B_OK; -#endif - } - - status_t Unlock() - { -#ifdef USE_BENAPHORE - if (atomic_add(&fCount, 1) < 0) -#endif - return release_sem(fSemaphore); -#ifdef USE_BENAPHORE - return B_OK; -#endif - } - - private: - sem_id fSemaphore; -#ifdef USE_BENAPHORE - vint32 fCount; -#endif -}; - -// a convenience class to lock a Semaphore object - -class Locker { - public: - Locker(Semaphore &lock) - : fLock(lock) - { - fStatus = lock.Lock(); - ASSERT(fStatus == B_OK); - } - - ~Locker() - { - if (fStatus == B_OK) - fLock.Unlock(); - } - - status_t Status() const - { - return fStatus; - } - - private: - Semaphore &fLock; - status_t fStatus; -}; - - -// #pragma mark - Recursive Lock - -class RecursiveLock { - public: - RecursiveLock(const char *name) - : -#ifdef USE_BENAPHORE - fSemaphore(create_sem(0, name)), - fCount(1), -#else - fSemaphore(create_sem(1, name)), -#endif - fOwner(-1) - { - } - - status_t InitCheck() const - { - if (fSemaphore < B_OK) - return fSemaphore; - - return B_OK; - } - - status_t LockWithTimeout(bigtime_t timeout) - { - thread_id thread = find_thread(NULL); - if (thread == fOwner) { - fOwnerCount++; - return B_OK; - } - - status_t status; -#ifdef USE_BENAPHORE - if (atomic_add(&fCount, -1) > 0) - status = B_OK; - else -#endif - status = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT, timeout); - - if (status == B_OK) { - fOwner = thread; - fOwnerCount = 1; - } - - return status; - } - - status_t Lock() - { - return LockWithTimeout(B_INFINITE_TIMEOUT); - } - - status_t Unlock() - { - thread_id thread = find_thread(NULL); - if (thread != fOwner) { - panic("RecursiveLock unlocked by %d, owned by %d\n", (int)thread, (int)fOwner); - } - - if (--fOwnerCount == 0) { - fOwner = -1; -#ifdef USE_BENAPHORE - if (atomic_add(&fCount, 1) < 0) -#endif - return release_sem(fSemaphore); - } - - return B_OK; - } - - thread_id Owner() const { return fOwner; } - int32 OwnerCount() const { return fOwnerCount; } - - private: - sem_id fSemaphore; -#ifdef USE_BENAPHORE - vint32 fCount; -#endif - thread_id fOwner; - int32 fOwnerCount; -}; - -// a convenience class to lock an RecursiveLock object - -class RecursiveLocker { - public: - RecursiveLocker(RecursiveLock &lock) - : fLock(lock) - { - fStatus = lock.Lock(); - ASSERT(fStatus == B_OK); - } - - ~RecursiveLocker() - { - if (fStatus == B_OK) - fLock.Unlock(); - } - - status_t Status() const - { - return fStatus; - } - - private: - RecursiveLock &fLock; - status_t fStatus; -}; - - -//**** Many Reader/Single Writer Lock +// #pragma mark - Many Reader/Single Writer Lock // This is a "fast" implementation of a single writer/many reader // locking scheme. It's fast because it uses the benaphore idea @@ -523,78 +329,4 @@ class WriteLocked { status_t fStatus; }; - -// A simple locking structure that doesn't use a semaphore - it's useful -// if you have to protect critical parts with a short runtime. -// It also allows to nest several locks for the same thread. - -class SimpleLock { - public: - SimpleLock() - : - fHolder(-1), - fCount(0) - { - } - - status_t Lock(bigtime_t time = 500) - { - int32 thisThread = find_thread(NULL); - int32 current; - while (1) { - /*if (fHolder == -1) { - current = fHolder; - fHolder = thisThread; - }*/ - current = atomic_test_and_set(&fHolder, thisThread, -1); - if (current == -1) - break; - if (current == thisThread) - break; - - snooze(time); - } - - // ToDo: the lock cannot fail currently! We may want - // to change this - atomic_add(&fCount, 1); - return B_OK; - } - - void Unlock() - { - if (atomic_add(&fCount, -1) == 1) - atomic_set(&fHolder, -1); - } - - bool IsLocked() const - { - return fHolder == find_thread(NULL); - } - - private: - vint32 fHolder; - vint32 fCount; -}; - -// A convenience class to lock the SimpleLock, note the -// different timing compared to the direct call - -class SimpleLocker { - public: - SimpleLocker(SimpleLock &lock,bigtime_t time = 1000) - : fLock(lock) - { - lock.Lock(time); - } - - ~SimpleLocker() - { - fLock.Unlock(); - } - - private: - SimpleLock &fLock; -}; - #endif /* LOCK_H */ diff --git a/src/add-ons/kernel/file_systems/bfs/Query.cpp b/src/add-ons/kernel/file_systems/bfs/Query.cpp index adcd00dbe0..0784601d11 100644 --- a/src/add-ons/kernel/file_systems/bfs/Query.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Query.cpp @@ -805,13 +805,13 @@ Equation::Match(Inode *inode, const char *attributeName, int32 type, const uint8 // we need to lock before accessing Inode::Name() nodeGetter.SetToNode(inode); - inode->SmallDataLock().Lock(); + recursive_lock_lock(&inode->SmallDataLock()); locked = true; // if not, check for "fake" attributes, "name", "size", "last_modified", buffer = (uint8 *)inode->Name(nodeGetter.Node()); if (buffer == NULL) { - inode->SmallDataLock().Unlock(); + recursive_lock_unlock(&inode->SmallDataLock()); return B_ERROR; } @@ -837,7 +837,7 @@ Equation::Match(Inode *inode, const char *attributeName, int32 type, const uint8 nodeGetter.SetToNode(inode); Inode *attribute; - inode->SmallDataLock().Lock(); + recursive_lock_lock(&inode->SmallDataLock()); small_data *smallData = inode->FindSmallData(nodeGetter.Node(), fAttribute); if (smallData != NULL) { buffer = smallData->Data(); @@ -846,7 +846,7 @@ Equation::Match(Inode *inode, const char *attributeName, int32 type, const uint8 locked = true; } else { // needed to unlock the small_data section as fast as possible - inode->SmallDataLock().Unlock(); + recursive_lock_unlock(&inode->SmallDataLock()); nodeGetter.Unset(); if (inode->GetAttribute(fAttribute, &attribute) == B_OK) { @@ -872,7 +872,7 @@ Equation::Match(Inode *inode, const char *attributeName, int32 type, const uint8 status = CompareTo(buffer, size) ? MATCH_OK : NO_MATCH; if (locked) - inode->SmallDataLock().Unlock(); + recursive_lock_unlock(&inode->SmallDataLock()); RETURN_ERROR(status); } diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.cpp b/src/add-ons/kernel/file_systems/bfs/Volume.cpp index 73fbf66cf2..2e1898e8a2 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Volume.cpp @@ -276,18 +276,20 @@ Volume::Volume(fs_volume *volume) : fVolume(volume), fBlockAllocator(this), - fLock("bfs volume"), fRootNode(NULL), fIndicesNode(NULL), fDirtyCachedBlocks(0), fUniqueID(0), fFlags(0) { + mutex_init(&fLock, "bfs volume"); + mutex_init(&fQueryLock, "bfs queries"); } Volume::~Volume() { + mutex_destroy(&fLock); } @@ -516,16 +518,13 @@ Volume::UpdateLiveQueries(Inode *inode, const char *attribute, int32 type, const uint8 *oldKey, size_t oldLength, const uint8 *newKey, size_t newLength) { - if (fQueryLock.Lock() < B_OK) - return; + MutexLocker _(fQueryLock); Query *query = NULL; while ((query = fQueries.Next(query)) != NULL) { query->LiveUpdate(inode, attribute, type, oldKey, oldLength, newKey, newLength); } - - fQueryLock.Unlock(); } @@ -545,24 +544,16 @@ Volume::CheckForLiveQuery(const char *attribute) void Volume::AddQuery(Query *query) { - if (fQueryLock.Lock() < B_OK) - return; - + MutexLocker _(fQueryLock); fQueries.Add(query); - - fQueryLock.Unlock(); } void Volume::RemoveQuery(Query *query) { - if (fQueryLock.Lock() < B_OK) - return; - + MutexLocker _(fQueryLock); fQueries.Remove(query); - - fQueryLock.Unlock(); } diff --git a/src/add-ons/kernel/file_systems/bfs/Volume.h b/src/add-ons/kernel/file_systems/bfs/Volume.h index 72f2118aee..b11b6b6e2c 100644 --- a/src/add-ons/kernel/file_systems/bfs/Volume.h +++ b/src/add-ons/kernel/file_systems/bfs/Volume.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de. * This file may be used under the terms of the MIT License. */ #ifndef VOLUME_H @@ -37,7 +37,7 @@ class Volume { bool IsValidSuperBlock(); bool IsReadOnly() const; void Panic(); - RecursiveLock &Lock(); + mutex &Lock(); block_run Root() const { return fSuperBlock.root_dir; } Inode *RootNode() const { return fRootNode; } @@ -117,7 +117,7 @@ class Volume { uint32 fAllocationGroupShift; BlockAllocator fBlockAllocator; - RecursiveLock fLock; + mutex fLock; Journal *fJournal; vint32 fLogStart, fLogEnd; @@ -126,7 +126,7 @@ class Volume { vint32 fDirtyCachedBlocks; - SimpleLock fQueryLock; + mutex fQueryLock; Chain fQueries; int32 fUniqueID; @@ -145,7 +145,7 @@ Volume::IsReadOnly() const } -inline RecursiveLock & +inline mutex & Volume::Lock() { return fLock; diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index daaa1b6ecd..242b32cbf2 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -149,7 +149,7 @@ bfs_read_fs_stat(fs_volume *_volume, struct fs_info *info) FUNCTION(); Volume *volume = (Volume *)_volume->private_volume; - RecursiveLocker locker(volume->Lock()); + MutexLocker locker(volume->Lock()); // File system flags. info->flags = B_FS_IS_PERSISTENT | B_FS_HAS_ATTR | B_FS_HAS_MIME @@ -181,7 +181,7 @@ bfs_write_fs_stat(fs_volume *_volume, const struct fs_info *info, uint32 mask) if (volume->IsReadOnly()) return B_READ_ONLY_DEVICE; - RecursiveLocker locker(volume->Lock()); + MutexLocker locker(volume->Lock()); status_t status = B_BAD_VALUE; diff --git a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h index 8e24fd98b4..2e61092004 100644 --- a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h +++ b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h @@ -12,6 +12,7 @@ #else // !BFS_SHELL +#include #include #include #include diff --git a/src/system/boot/loader/file_systems/bfs/Jamfile b/src/system/boot/loader/file_systems/bfs/Jamfile index 2dcf6a3795..f5840e9e48 100644 --- a/src/system/boot/loader/file_systems/bfs/Jamfile +++ b/src/system/boot/loader/file_systems/bfs/Jamfile @@ -1,8 +1,7 @@ SubDir HAIKU_TOP src system boot loader file_systems bfs ; -UsePrivateHeaders [ FDirName kernel boot platform $(TARGET_BOOT_PLATFORM) ] ; -UsePrivateHeaders [ FDirName kernel disk_device_manager ] ; -UsePrivateHeaders kernel shared storage ; +UsePrivateKernelHeaders ; +UsePrivateHeaders shared storage ; SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_systems bfs ;