diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 2e2f97e54e..1cb1c0a19a 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -175,6 +175,8 @@ InodeAllocator::~InodeAllocator() fInode->Node().flags &= ~HOST_ENDIAN_TO_BFS_INT32(INODE_IN_USE); // this unblocks any pending bfs_read_vnode() calls fInode->Free(*fTransaction); + fTransaction->RemoveInode(fInode); + remove_vnode(volume->FSVolume(), fInode->ID()); } else volume->Free(*fTransaction, fRun); diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index 5b9e3b3553..6541598127 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -1080,6 +1080,11 @@ Transaction::Start(Volume* volume, off_t refBlock) } +/*! Adds an inode to this transaction. This means that the inode will be write + locked until the transaction ended. + To ensure that the inode will stay valid until that point, an extra reference + is acquired to it as long as this transaction stays active. +*/ void Transaction::AddInode(Inode* inode) { @@ -1101,6 +1106,19 @@ Transaction::AddInode(Inode* inode) } +void +Transaction::RemoveInode(Inode* inode) +{ + if (fJournal == NULL) + panic("Transaction is not running!"); + + fLockedInodes.Remove(inode); + rw_lock_write_unlock(&inode->fLock); + if (!GetVolume()->IsInitializing()) + put_vnode(GetVolume()->FSVolume(), inode->ID()); +} + + void Transaction::_UnlockInodes() { diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.h b/src/add-ons/kernel/file_systems/bfs/Journal.h index b5b40bc488..b4a2195b09 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.h +++ b/src/add-ons/kernel/file_systems/bfs/Journal.h @@ -163,6 +163,7 @@ public: { return fJournal->TransactionID(); } void AddInode(Inode* inode); + void RemoveInode(Inode* inode); private: Transaction(const Transaction& other);