Commit 64194c24 authored by Dave Kleikamp's avatar Dave Kleikamp

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.
parent e2423dc0
......@@ -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() */
......
......@@ -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));
......
......@@ -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);
......
......@@ -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 */
......
......@@ -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)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment