From 923e3aaf6f7474dac6ccc017302a6b20136f5d3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sat, 21 Jan 2006 13:35:08 +0000 Subject: [PATCH] Fixed two crucial bugs: * When aborting the first sub-transaction, BFS didn't recognize this correctly, and aborted it via cache_abort_transaction() instead of cache_abort_sub_transaction() - that not only reversed the whole transaction, but also let subsequent cache_start_sub_transaction() fail (as there was no transaction to continue anymore). Reported in a reproducible way by Jerome Duval. * Haiku didn't want to replay logs anymore - the off-by-one fix I did in r14428 was not complete, it only let Be's BFS replay our logs, but our's rejected them afterwards. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16018 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/Journal.cpp | 10 ++++++++-- src/add-ons/kernel/file_systems/bfs/Journal.h | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index 4a434c6e18..f7dc26c6a7 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -300,7 +300,8 @@ Journal::Journal(Volume *volume) fLogSize(volume->Log().length), fMaxTransactionSize(fLogSize / 4 - 5), fUsed(0), - fUnwrittenTransactions(0) + fUnwrittenTransactions(0), + fHasSubtransaction(false) { if (fMaxTransactionSize > fLogSize / 2) fMaxTransactionSize = fLogSize / 2 - 5; @@ -330,10 +331,13 @@ Journal::InitCheck() status_t Journal::_CheckRunArray(const run_array *array) { - int32 maxRuns = run_array::MaxRuns(fVolume->BlockSize()); + int32 maxRuns = run_array::MaxRuns(fVolume->BlockSize()) - 1; + // the -1 works around an off-by-one bug in Be's BFS implementation, + // same as in run_array::MaxRuns() if (array->MaxRuns() != maxRuns || array->CountRuns() > maxRuns || array->CountRuns() <= 0) { + dprintf("run count: %ld, array max: %ld, max runs: %ld\n", array->CountRuns(), array->MaxRuns(), maxRuns); FATAL(("Log entry has broken header!\n")); return B_ERROR; } @@ -507,6 +511,7 @@ Journal::_WriteTransactionToLog() // changed blocks back to disk immediately fUnwrittenTransactions = 0; + fHasSubtransaction = false; int32 blockShift = fVolume->BlockShift(); off_t logOffset = fVolume->ToBlock(fVolume->Log()) << blockShift; @@ -721,6 +726,7 @@ Journal::Lock(Transaction *owner) if (fUnwrittenTransactions > 0) { // start a sub transaction cache_start_sub_transaction(fVolume->BlockCache(), fTransactionID); + fHasSubtransaction = true; } else fTransactionID = cache_start_transaction(fVolume->BlockCache()); diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.h b/src/add-ons/kernel/file_systems/bfs/Journal.h index aa6690a2fa..8191a0db8c 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.h +++ b/src/add-ons/kernel/file_systems/bfs/Journal.h @@ -60,7 +60,7 @@ class Journal { inline uint32 FreeLogBlocks() const; private: - bool _HasSubTransaction() { return fUnwrittenTransactions > 1; } + bool _HasSubTransaction() { return fHasSubtransaction; } uint32 _TransactionSize() const; status_t _WriteTransactionToLog(); status_t _CheckRunArray(const run_array *array); @@ -77,6 +77,7 @@ class Journal { LogEntryList fEntries; bigtime_t fTimestamp; int32 fTransactionID; + bool fHasSubtransaction; };