[Ocfs2-devel] [patch 1/2] ocfs2-1.2: Remove inode_alloc from handle when inode allocation fails.
tao.ma at oracle.com
tao.ma at oracle.com
Wed Apr 30 00:34:58 PDT 2008
When we fail to alloc an inode from the inode_alloc:000X, we need to
remove that allocation inode from current transaction. Otherwise
we may encounter dead lock when other nodes want to steal inode
from us.
Index: ocfs2-1.2/fs/ocfs2/journal.c
===================================================================
--- ocfs2-1.2.orig/fs/ocfs2/journal.c 2008-04-30 13:59:12.000000000 +0800
+++ ocfs2-1.2/fs/ocfs2/journal.c 2008-04-30 14:09:54.000000000 +0800
@@ -228,6 +228,53 @@ void ocfs2_handle_add_inode(struct ocfs2
list_add_tail(&(OCFS2_I(inode)->ip_handle_list), &(handle->inode_list));
}
+/*
+ * This method is a bit tricky and break up the policy of normal inode
+ * operation in a journal transaction. It will remove the alloc inode
+ * and free its lock from the transaction.
+ * So it should only be used in inode stealing.
+ *
+ * The 1st part is copied from ocfs2_handle_unlock_inodes.
+ * The 2nd part is copied from ocfs2_handle_cleanup_locks.
+ */
+void ocfs2_handle_remove_alloc_inode(struct ocfs2_journal_handle *handle,
+ struct inode *inode)
+{
+ struct list_head *p, *n;
+ struct ocfs2_journal_lock *lock;
+
+ BUG_ON(!handle);
+ BUG_ON(!inode);
+ BUG_ON(!OCFS2_I(inode)->ip_handle);
+ BUG_ON(list_empty(&OCFS2_I(inode)->ip_handle_list));
+
+ OCFS2_I(inode)->ip_handle = NULL;
+ list_del_init(&OCFS2_I(inode)->ip_handle_list);
+
+ mutex_unlock(&inode->i_mutex);
+ iput(inode);
+
+ list_for_each_safe(p, n, &(handle->locks)) {
+ lock = list_entry(p, struct ocfs2_journal_lock,
+ jl_lock_list);
+
+ if (inode == lock->jl_inode) {
+ list_del(&lock->jl_lock_list);
+ handle->num_locks--;
+
+ ocfs2_meta_unlock(inode, 1);
+ if (atomic_read(&inode->i_count) == 1)
+ mlog(ML_ERROR,
+ "Inode %"MLFu64", "
+ "I'm doing a last iput for!",
+ OCFS2_I(inode)->ip_blkno);
+ iput(inode);
+ kmem_cache_free(ocfs2_lock_cache, lock);
+ break;
+ }
+ }
+}
+
static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle)
{
struct list_head *p, *n;
Index: ocfs2-1.2/fs/ocfs2/journal.h
===================================================================
--- ocfs2-1.2.orig/fs/ocfs2/journal.h 2008-04-30 13:59:12.000000000 +0800
+++ ocfs2-1.2/fs/ocfs2/journal.h 2008-04-30 14:05:43.000000000 +0800
@@ -256,6 +256,9 @@ static inline void ocfs2_checkpoint_inod
* to be released at the end of that handle. Locks
* will be released in the order that they are added.
* ocfs2_handle_add_inode - Add a locked inode to a transaction.
+ *
+ * ocfs2_handle_remove_alloc_inode - Remove a locked alloc inode from a
+ * transaction. It should only be used in inode stealing.
*/
/* You must always start_trans with a number of buffs > 0, but it's
@@ -318,6 +321,8 @@ int ocfs2_handle_add_lo
void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle,
struct inode *inode);
+void ocfs2_handle_remove_alloc_inode(struct ocfs2_journal_handle *handle,
+ struct inode *inode);
/*
* Credit Macros:
* Convenience macros to calculate number of credits needed.
--
More information about the Ocfs2-devel
mailing list