* The InodeAllocator must remove the inode from the transaction before deleting

it, otherwise the transaction would access already freed memory when trying
  to release its write lock of the inode.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29481 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-03-12 14:24:36 +00:00
parent c9bc3be3d9
commit 41a6cf82b3
3 changed files with 21 additions and 0 deletions

View File

@ -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);

View File

@ -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()
{

View File

@ -163,6 +163,7 @@ public:
{ return fJournal->TransactionID(); }
void AddInode(Inode* inode);
void RemoveInode(Inode* inode);
private:
Transaction(const Transaction& other);