From 41a6cf82b37f3225a11c11c8f74f3e9f8193e954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 12 Mar 2009 14:24:36 +0000 Subject: [PATCH] * 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 --- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 2 ++ .../kernel/file_systems/bfs/Journal.cpp | 18 ++++++++++++++++++ src/add-ons/kernel/file_systems/bfs/Journal.h | 1 + 3 files changed, 21 insertions(+) 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);