]> git.neil.brown.name Git - history.git/commitdiff
JFS: Avoid incrementing i_count on file create
authorDave Kleikamp <shaggy@austin.ibm.com>
Mon, 8 Mar 2004 08:40:34 +0000 (02:40 -0600)
committerDave Kleikamp <shaggy@austin.ibm.com>
Mon, 8 Mar 2004 08:40:34 +0000 (02:40 -0600)
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.

fs/jfs/jfs_incore.h
fs/jfs/jfs_inode.c
fs/jfs/jfs_txnmgr.c
fs/jfs/jfs_txnmgr.h
fs/jfs/namei.c

index 16ae648cb979cdeaaec9d6e85b596bb14a34bcb9..1a6ec59da9352d525cfc1e1f0e909f3579d43b75 100644 (file)
@@ -114,7 +114,6 @@ struct jfs_inode_info {
  * 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() */
index cdadd1e099cb3ed43360424d60ba41562df1bfb8..3e8592b9b0fcb5feb59131d42e37729a15e526da 100644 (file)
@@ -72,7 +72,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        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));
index ba8b19c258154dce66aa3f19b1b4fef2426772e5..4b0c8eb3a5f422ccc56f182b30b6244e5b68494c 100644 (file)
@@ -1240,8 +1240,8 @@ int txCommit(tid_t tid,           /* transaction identifier */
         * 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 @@ int txCommit(tid_t tid,         /* transaction identifier */
                 * 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 @@ static void txUpdateMap(struct tblock * tblk)
         * 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);
index 78046900fff01489f20166977e193fe7195ee9bd..294d83223ad62065ed44cac0de07d68e1eab07b3 100644 (file)
@@ -62,7 +62,11 @@ struct tblock {
                                         * 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 */
index 8f7ea78e058cde333b86d5e0133414443781e020..472c43ebea1df11aa92b86ca0e31da4a67129e85 100644 (file)
@@ -104,7 +104,8 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
 
        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 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
 
        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 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry)
 
        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 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
                }
                tblk = tid_to_tblock(tid);
                tblk->xflag |= COMMIT_DELETE;
-               tblk->ip = ip;
+               tblk->u.ip = ip;
        }
 
        /*
@@ -889,7 +891,8 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
 
        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 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        }
                        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 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                        }
                        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 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
 
        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)))