Implemented basic sub transaction support - seems to work so far, but I haven't

tested it heavily yet.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14432 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-10-19 16:49:01 +00:00
parent ca7c5a9e13
commit 9a99234b1a
2 changed files with 34 additions and 34 deletions

View File

@ -300,7 +300,7 @@ Journal::Journal(Volume *volume)
fLogSize(volume->Log().length),
fMaxTransactionSize(fLogSize / 4 - 5),
fUsed(0),
fTransactionsInEntry(0)
fUnwrittenTransactions(0)
{
if (fMaxTransactionSize > fLogSize / 2)
fMaxTransactionSize = fLogSize / 2 - 5;
@ -501,13 +501,12 @@ Journal::_blockNotify(int32 transactionID, void *arg)
status_t
Journal::WriteLogEntry()
Journal::_WriteTransactionToLog()
{
// ToDo: in case of a failure, we need a backup plan like writing all
// changed blocks back to disk immediately
fTransactionsInEntry = 0;
fHasChangedBlocks = false;
fUnwrittenTransactions = 0;
int32 blockShift = fVolume->BlockShift();
off_t logOffset = fVolume->ToBlock(fVolume->Log()) << blockShift;
@ -679,8 +678,8 @@ Journal::FlushLogAndBlocks()
// write the current log entry to disk
if (fTransactionID != -1 /*&& TransactionSize() != 0*/) {
status = WriteLogEntry();
if (fUnwrittenTransactions != 0 && _TransactionSize() != 0) {
status = _WriteTransactionToLog();
if (status < B_OK)
FATAL(("writing current log entry failed: %s\n", strerror(status)));
}
@ -712,7 +711,12 @@ Journal::Lock(Transaction *owner)
fOwner = owner;
fTransactionID = cache_start_transaction(fVolume->BlockCache());
if (fUnwrittenTransactions > 0) {
// start a sub transaction
cache_start_sub_transaction(fVolume->BlockCache(), fTransactionID);
} else
fTransactionID = cache_start_transaction(fVolume->BlockCache());
if (fTransactionID < B_OK) {
fLock.Unlock();
return fTransactionID;
@ -730,7 +734,6 @@ Journal::Unlock(Transaction *owner, bool success)
// ToDo: what about failing transactions that do not unlock?
_TransactionDone(success);
fTransactionID = -1;
fTimestamp = system_time();
fOwner = NULL;
}
@ -739,40 +742,38 @@ Journal::Unlock(Transaction *owner, bool success)
}
uint32
Journal::_TransactionSize() const
{
int32 count = cache_blocks_in_transaction(fVolume->BlockCache(), fTransactionID);
if (count < 0)
return 0;
return count;
}
status_t
Journal::_TransactionDone(bool success)
{
if (!success) {
cache_abort_transaction(fVolume->BlockCache(), fTransactionID);
return B_OK;
}
// ToDo:
/*
if (!success && fTransactionsInEntry == 0) {
// we can safely abort the transaction
sorted_array *array = fArray.Array();
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]);
}
if (_HasSubTransaction())
cache_abort_sub_transaction(fVolume->BlockCache(), fTransactionID);
else
cache_abort_transaction(fVolume->BlockCache(), fTransactionID);
fUnwrittenTransactions--;
return B_OK;
}
// Up to a maximum size, we will just batch several
// transactions together to improve speed
if (TransactionSize() < fMaxTransactionSize) {
fTransactionsInEntry++;
fHasChangedBlocks = false;
if (_TransactionSize() < fMaxTransactionSize) {
fUnwrittenTransactions++;
return B_OK;
}
*/
return WriteLogEntry();
return _WriteTransactionToLog();
}
@ -785,7 +786,6 @@ Journal::LogBlocks(off_t blockNumber, const uint8 *buffer, size_t numBlocks)
if (TransactionSize() + numBlocks + 1 > fLogSize)
return B_DEVICE_FULL;
fHasChangedBlocks = true;
int32 blockSize = fVolume->BlockSize();
for (;numBlocks-- > 0; blockNumber++, buffer += blockSize) {

View File

@ -49,11 +49,9 @@ class Journal {
status_t ReplayLog();
status_t WriteLogEntry();
status_t LogBlocks(off_t blockNumber, const uint8 *buffer, size_t numBlocks);
Transaction *CurrentTransaction() const { return fOwner; }
// uint32 TransactionSize() const { return fArray.CountItems() + fArray.BlocksUsed(); }
status_t FlushLogAndBlocks();
Volume *GetVolume() const { return fVolume; }
@ -62,6 +60,9 @@ class Journal {
inline uint32 FreeLogBlocks() const;
private:
bool _HasSubTransaction() { return fUnwrittenTransactions > 1; }
uint32 _TransactionSize() const;
status_t _WriteTransactionToLog();
status_t _CheckRunArray(const run_array *array);
status_t _ReplayRunArray(int32 *start);
status_t _TransactionDone(bool success);
@ -71,10 +72,9 @@ class Journal {
RecursiveLock fLock;
Transaction *fOwner;
uint32 fLogSize, fMaxTransactionSize, fUsed;
int32 fTransactionsInEntry;
int32 fUnwrittenTransactions;
SimpleLock fEntriesLock;
LogEntryList fEntries;
bool fHasChangedBlocks;
bigtime_t fTimestamp;
int32 fTransactionID;
};