[PATCH] JFS: Avoid rare deadlock (3 of 3)

Dave Kleikamp <[email protected]> Tue, 22 Apr 2003 09:42:45 -0500
Newsgroups gmane.comp.file-systems.jfs.patches
Message-ID <[email protected]>
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1101.1.2 -> 1.1101.1.3
#	 fs/jfs/jfs_txnmgr.c	1.25    -> 1.26   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/04/17	[email protected]	1.1101.1.3
# JFS: Avoid rare deadlock
# --------------------------------------------
#
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Tue Apr 22 09:19:01 2003
+++ b/fs/jfs/jfs_txnmgr.c	Tue Apr 22 09:19:01 2003
@@ -1220,8 +1220,21 @@
 	 * Ensure that inode isn't reused before
 	 * lazy commit thread finishes processing
 	 */
-	if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE))
+	if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) {
 		atomic_inc(&tblk->ip->i_count);
+		/*
+		 * Avoid a rare deadlock
+		 *
+		 * If the inode is locked, we may be blocked in
+		 * jfs_commit_inode.  If so, we don't want the
+		 * lazy_commit thread doing the last iput() on the inode
+		 * since that may block on the locked inode.  Instead,
+		 * commit the transaction synchronously, so the last iput
+		 * will be done by the calling thread (or later)
+		 */
+		if (tblk->ip->i_state & I_LOCK)
+			tblk->xflag &= ~COMMIT_LAZY;
+	}
 
 	ASSERT((!(tblk->xflag & COMMIT_DELETE)) ||
 	       ((tblk->ip->i_nlink == 0) &&