[Ocfs2-commits] smushran commits r3099 - branches/ocfs2-1.2/fs/ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Mon May 19 10:48:05 PDT 2008
Author: smushran
Date: 2008-05-19 10:48:05 -0700 (Mon, 19 May 2008)
New Revision: 3099
Modified:
branches/ocfs2-1.2/fs/ocfs2/journal.c
branches/ocfs2-1.2/fs/ocfs2/journal.h
Log:
ocfs2: Remove inode_alloc from handle when inode allocation fails.
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.
Authored-off-by: tma
Signed-off-by: mfasheh
Modified: branches/ocfs2-1.2/fs/ocfs2/journal.c
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/journal.c 2008-05-06 20:45:25 UTC (rev 3098)
+++ branches/ocfs2-1.2/fs/ocfs2/journal.c 2008-05-19 17:48:05 UTC (rev 3099)
@@ -228,6 +228,53 @@
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;
Modified: branches/ocfs2-1.2/fs/ocfs2/journal.h
===================================================================
--- branches/ocfs2-1.2/fs/ocfs2/journal.h 2008-05-06 20:45:25 UTC (rev 3098)
+++ branches/ocfs2-1.2/fs/ocfs2/journal.h 2008-05-19 17:48:05 UTC (rev 3099)
@@ -256,6 +256,9 @@
* 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 @@
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-commits
mailing list