diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index f0f7b881a8..3647bfb6e8 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -17,7 +17,6 @@ Journal::Journal(Volume *volume) fVolume(volume), fLock("bfs journal"), fOwner(NULL), - fOwningThread(-1), fArray(volume->BlockSize()), fLogSize(volume->Log().length), fMaxTransactionSize(fLogSize / 4 - 5), @@ -338,10 +337,8 @@ Journal::Lock(Transaction *owner) return B_OK; status_t status = fLock.Lock(); - if (status == B_OK) { + if (status == B_OK) fOwner = owner; - fOwningThread = find_thread(NULL); - } // if the last transaction is older than 2 secs, start a new one if (fTransactionsInEntry != 0 && system_time() - fTimestamp > 2000000L) @@ -361,11 +358,27 @@ Journal::Unlock(Transaction *owner, bool success) fTimestamp = system_time(); fOwner = NULL; - fOwningThread = -1; fLock.Unlock(); } +/** If there is a current transaction that the current thread has + * started, this function will give you access to it. + */ + +Transaction * +Journal::CurrentTransaction() +{ + if (fLock.LockWithTimeout(0) != B_OK) + return NULL; + + Transaction *owner = fOwner; + fLock.Unlock(); + + return owner; +} + + status_t Journal::TransactionDone(bool success) { diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.h b/src/add-ons/kernel/file_systems/bfs/Journal.h index 05f550e39f..aa0904dcbe 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.h +++ b/src/add-ons/kernel/file_systems/bfs/Journal.h @@ -53,8 +53,7 @@ class Journal { status_t WriteLogEntry(); status_t LogBlocks(off_t blockNumber, const uint8 *buffer, size_t numBlocks); - thread_id CurrentThread() const { return fOwningThread; } - Transaction *CurrentTransaction() const { return fOwner; } + Transaction *CurrentTransaction(); uint32 TransactionSize() const { return fArray.CountItems() + fArray.BlocksUsed(); } status_t FlushLogAndBlocks(); @@ -69,9 +68,8 @@ class Journal { status_t TransactionDone(bool success); Volume *fVolume; - Semaphore fLock; + RecursiveLock fLock; Transaction *fOwner; - thread_id fOwningThread; BlockArray fArray; uint32 fLogSize, fMaxTransactionSize, fUsed; int32 fTransactionsInEntry; 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 ab401bc813..480d64bf8e 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -459,13 +459,16 @@ bfs_remove_vnode(void *_ns, void *_node, char reenter) // If the inode isn't in use anymore, we were called before // bfs_unlink() returns - in this case, we can just use the // transaction which has already deleted the inode. - Transaction localTransaction, *transaction = &localTransaction; - Journal *journal = volume->GetJournal(volume->ToBlock(inode->Parent())); + Transaction localTransaction, *transaction = NULL; - if (journal != NULL && journal->CurrentThread() == find_thread(NULL)) + Journal *journal = volume->GetJournal(volume->ToBlock(inode->Parent())); + if (journal != NULL) transaction = journal->CurrentTransaction(); - else + + if (transaction == NULL) { + transaction = &localTransaction; localTransaction.Start(volume, inode->BlockNumber()); + } status_t status = inode->Free(transaction); if (status == B_OK) {