[PATCH] Avoid incrementing i_count on file create (3 of 4)

[email protected] Mon, 8 Mar 2004 17:04:45 -0600
Newsgroups gmane.comp.file-systems.jfs.patches
Message-ID <[email protected]>
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/03/08 14:40:34-06:00 [email protected] 
#   JFS: Avoid incrementing i_count on file create
#   
#   Committing a transaction creating a file required insuring that the
#   inode stayed in cache until the journal was written to.  i_count was
#   being incremented until the transaction was complete.
#   
#   However, incrementing i_count caused fcntl(S_SETLEASE) to fail.  I
#   reworked the transaction code so that the inode does not have to
#   stay in-memory while the transaction is being committed.
#   
#   Thanks to Steve French for figuring out why setlease was failing.
# 
diff -Nru a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
--- a/fs/jfs/jfs_incore.h	Mon Mar  8 17:02:13 2004
+++ b/fs/jfs/jfs_incore.h	Mon Mar  8 17:02:13 2004
@@ -114,7 +114,6 @@
  * cflag
  */
 enum cflags {
-	COMMIT_New,		/* never committed inode   */
 	COMMIT_Nolink,		/* inode committed with zero link count */
 	COMMIT_Inlineea,	/* commit inode inline EA */
 	COMMIT_Freewmap,	/* free WMAP at iClose() */
diff -Nru a/fs/jfs/jfs_inode.c b/fs/jfs/jfs_inode.c
--- a/fs/jfs/jfs_inode.c	Mon Mar  8 17:02:13 2004
+++ b/fs/jfs/jfs_inode.c	Mon Mar  8 17:02:13 2004
@@ -72,7 +72,6 @@
 	inode->i_generation = JFS_SBI(sb)->gengen++;
 
 	jfs_inode->cflag = 0;
-	set_cflag(COMMIT_New, inode);
 
 	/* Zero remaining fields */
 	memset(&jfs_inode->acl, 0, sizeof(dxd_t));
diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
--- a/fs/jfs/jfs_txnmgr.c	Mon Mar  8 17:02:13 2004
+++ b/fs/jfs/jfs_txnmgr.c	Mon Mar  8 17:02:13 2004
@@ -1240,8 +1240,8 @@
 	 * Ensure that inode isn't reused before
 	 * lazy commit thread finishes processing
 	 */
-	if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) {
-		atomic_inc(&tblk->ip->i_count);
+	if (tblk->xflag & COMMIT_DELETE) {
+		atomic_inc(&tblk->u.ip->i_count);
 		/*
 		 * Avoid a rare deadlock
 		 *
@@ -1252,13 +1252,13 @@
 		 * commit the transaction synchronously, so the last iput
 		 * will be done by the calling thread (or later)
 		 */
-		if (tblk->ip->i_state & I_LOCK)
+		if (tblk->u.ip->i_state & I_LOCK)
 			tblk->xflag &= ~COMMIT_LAZY;
 	}
 
 	ASSERT((!(tblk->xflag & COMMIT_DELETE)) ||
-	       ((tblk->ip->i_nlink == 0) &&
-		!test_cflag(COMMIT_Nolink, tblk->ip)));
+	       ((tblk->u.ip->i_nlink == 0) &&
+		!test_cflag(COMMIT_Nolink, tblk->u.ip)));
 
 	/*
 	 *      write COMMIT log record
@@ -2360,23 +2360,17 @@
 	 * unlock mapper/write lock
 	 */
 	if (tblk->xflag & COMMIT_CREATE) {
-		ip = tblk->ip;
-
-		ASSERT(test_cflag(COMMIT_New, ip));
-		clear_cflag(COMMIT_New, ip);
-
-		diUpdatePMap(ipimap, ip->i_ino, FALSE, tblk);
+		diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
 		ipimap->i_state |= I_DIRTY;
 		/* update persistent block allocation map
 		 * for the allocation of inode extent;
 		 */
 		pxdlock.flag = mlckALLOCPXD;
-		pxdlock.pxd = JFS_IP(ip)->ixpxd;
+		pxdlock.pxd = tblk->u.ixpxd;
 		pxdlock.index = 1;
-		txAllocPMap(ip, (struct maplock *) & pxdlock, tblk);
-		iput(ip);
+		txAllocPMap(ipimap, (struct maplock *) & pxdlock, tblk);
 	} else if (tblk->xflag & COMMIT_DELETE) {
-		ip = tblk->ip;
+		ip = tblk->u.ip;
 		diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
 		ipimap->i_state |= I_DIRTY;
 		iput(ip);
diff -Nru a/fs/jfs/jfs_txnmgr.h b/fs/jfs/jfs_txnmgr.h
--- a/fs/jfs/jfs_txnmgr.h	Mon Mar  8 17:02:13 2004
+++ b/fs/jfs/jfs_txnmgr.h	Mon Mar  8 17:02:13 2004
@@ -62,7 +62,11 @@
 					 * ready transactions wait on this
 					 * event for group commit completion.
 					 */
-	struct inode *ip;	/* inode being created or deleted */
+	union {
+		struct inode *ip; /* inode being deleted */
+		pxd_t ixpxd;	/* pxd of inode extent for created inode */
+	} u;
+	u32 ino;		/* inode number being created */
 };
 
 extern struct tblock *TxBlock;	/* transaction block table */
diff -Nru a/fs/jfs/namei.c b/fs/jfs/namei.c
--- a/fs/jfs/namei.c	Mon Mar  8 17:02:13 2004
+++ b/fs/jfs/namei.c	Mon Mar  8 17:02:13 2004
@@ -104,7 +104,8 @@
 
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_CREATE;
-	tblk->ip = ip;
+	tblk->ino = ip->i_ino;
+	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
 	iplist[0] = dip;
 	iplist[1] = ip;
@@ -230,7 +231,8 @@
 
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_CREATE;
-	tblk->ip = ip;
+	tblk->ino = ip->i_ino;
+	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
 	iplist[0] = dip;
 	iplist[1] = ip;
@@ -346,7 +348,7 @@
 
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_DELETE;
-	tblk->ip = ip;
+	tblk->u.ip = ip;
 
 	/*
 	 * delete the entry of target directory from parent directory
@@ -505,7 +507,7 @@
 		}
 		tblk = tid_to_tblock(tid);
 		tblk->xflag |= COMMIT_DELETE;
-		tblk->ip = ip;
+		tblk->u.ip = ip;
 	}
 
 	/*
@@ -889,7 +891,8 @@
 
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_CREATE;
-	tblk->ip = ip;
+	tblk->ino = ip->i_ino;
+	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
 	/*
 	 * create entry for symbolic link in parent directory
@@ -1151,7 +1154,7 @@
 			}
 			tblk = tid_to_tblock(tid);
 			tblk->xflag |= COMMIT_DELETE;
-			tblk->ip = new_ip;
+			tblk->u.ip = new_ip;
 		} else if (new_ip->i_nlink == 0) {
 			assert(!test_cflag(COMMIT_Nolink, new_ip));
 			/* free block resources */
@@ -1162,7 +1165,7 @@
 			}
 			tblk = tid_to_tblock(tid);
 			tblk->xflag |= COMMIT_DELETE;
-			tblk->ip = new_ip;
+			tblk->u.ip = new_ip;
 		} else {
 			new_ip->i_ctime = CURRENT_TIME;
 			mark_inode_dirty(new_ip);
@@ -1347,7 +1350,8 @@
 
 	tblk = tid_to_tblock(tid);
 	tblk->xflag |= COMMIT_CREATE;
-	tblk->ip = ip;
+	tblk->ino = ip->i_ino;
+	tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
 
 	ino = ip->i_ino;
 	if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack)))