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 { ...@@ -114,7 +114,6 @@ struct jfs_inode_info {
* cflag * cflag
*/ */
enum cflags { enum cflags {
COMMIT_New, /* never committed inode */
COMMIT_Nolink, /* inode committed with zero link count */ COMMIT_Nolink, /* inode committed with zero link count */
COMMIT_Inlineea, /* commit inode inline EA */ COMMIT_Inlineea, /* commit inode inline EA */
COMMIT_Freewmap, /* free WMAP at iClose() */ COMMIT_Freewmap, /* free WMAP at iClose() */
......
...@@ -72,7 +72,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode) ...@@ -72,7 +72,6 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
inode->i_generation = JFS_SBI(sb)->gengen++; inode->i_generation = JFS_SBI(sb)->gengen++;
jfs_inode->cflag = 0; jfs_inode->cflag = 0;
set_cflag(COMMIT_New, inode);
/* Zero remaining fields */ /* Zero remaining fields */
memset(&jfs_inode->acl, 0, sizeof(dxd_t)); memset(&jfs_inode->acl, 0, sizeof(dxd_t));
......
...@@ -1240,8 +1240,8 @@ int txCommit(tid_t tid, /* transaction identifier */ ...@@ -1240,8 +1240,8 @@ int txCommit(tid_t tid, /* transaction identifier */
* Ensure that inode isn't reused before * Ensure that inode isn't reused before
* lazy commit thread finishes processing * lazy commit thread finishes processing
*/ */
if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) { if (tblk->xflag & COMMIT_DELETE) {
atomic_inc(&tblk->ip->i_count); atomic_inc(&tblk->u.ip->i_count);
/* /*
* Avoid a rare deadlock * Avoid a rare deadlock
* *
...@@ -1252,13 +1252,13 @@ int txCommit(tid_t tid, /* transaction identifier */ ...@@ -1252,13 +1252,13 @@ int txCommit(tid_t tid, /* transaction identifier */
* commit the transaction synchronously, so the last iput * commit the transaction synchronously, so the last iput
* will be done by the calling thread (or later) * 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; tblk->xflag &= ~COMMIT_LAZY;
} }
ASSERT((!(tblk->xflag & COMMIT_DELETE)) || ASSERT((!(tblk->xflag & COMMIT_DELETE)) ||
((tblk->ip->i_nlink == 0) && ((tblk->u.ip->i_nlink == 0) &&
!test_cflag(COMMIT_Nolink, tblk->ip))); !test_cflag(COMMIT_Nolink, tblk->u.ip)));
/* /*
* write COMMIT log record * write COMMIT log record
...@@ -2360,23 +2360,17 @@ static void txUpdateMap(struct tblock * tblk) ...@@ -2360,23 +2360,17 @@ static void txUpdateMap(struct tblock * tblk)
* unlock mapper/write lock * unlock mapper/write lock
*/ */
if (tblk->xflag & COMMIT_CREATE) { if (tblk->xflag & COMMIT_CREATE) {
ip = tblk->ip; diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
ASSERT(test_cflag(COMMIT_New, ip));
clear_cflag(COMMIT_New, ip);
diUpdatePMap(ipimap, ip->i_ino, FALSE, tblk);
ipimap->i_state |= I_DIRTY; ipimap->i_state |= I_DIRTY;
/* update persistent block allocation map /* update persistent block allocation map
* for the allocation of inode extent; * for the allocation of inode extent;
*/ */
pxdlock.flag = mlckALLOCPXD; pxdlock.flag = mlckALLOCPXD;
pxdlock.pxd = JFS_IP(ip)->ixpxd; pxdlock.pxd = tblk->u.ixpxd;
pxdlock.index = 1; pxdlock.index = 1;
txAllocPMap(ip, (struct maplock *) & pxdlock, tblk); txAllocPMap(ipimap, (struct maplock *) & pxdlock, tblk);
iput(ip);
} else if (tblk->xflag & COMMIT_DELETE) { } else if (tblk->xflag & COMMIT_DELETE) {
ip = tblk->ip; ip = tblk->u.ip;
diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk); diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
ipimap->i_state |= I_DIRTY; ipimap->i_state |= I_DIRTY;
iput(ip); iput(ip);
......
...@@ -62,7 +62,11 @@ struct tblock { ...@@ -62,7 +62,11 @@ struct tblock {
* ready transactions wait on this * ready transactions wait on this
* event for group commit completion. * 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 */ extern struct tblock *TxBlock; /* transaction block table */
......
...@@ -104,7 +104,8 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode, ...@@ -104,7 +104,8 @@ int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE; tblk->xflag |= COMMIT_CREATE;
tblk->ip = ip; tblk->ino = ip->i_ino;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
iplist[0] = dip; iplist[0] = dip;
iplist[1] = ip; iplist[1] = ip;
...@@ -230,7 +231,8 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) ...@@ -230,7 +231,8 @@ int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE; tblk->xflag |= COMMIT_CREATE;
tblk->ip = ip; tblk->ino = ip->i_ino;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
iplist[0] = dip; iplist[0] = dip;
iplist[1] = ip; iplist[1] = ip;
...@@ -346,7 +348,7 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry) ...@@ -346,7 +348,7 @@ int jfs_rmdir(struct inode *dip, struct dentry *dentry)
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_DELETE; tblk->xflag |= COMMIT_DELETE;
tblk->ip = ip; tblk->u.ip = ip;
/* /*
* delete the entry of target directory from parent directory * delete the entry of target directory from parent directory
...@@ -505,7 +507,7 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -505,7 +507,7 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
} }
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_DELETE; 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) ...@@ -889,7 +891,8 @@ int jfs_symlink(struct inode *dip, struct dentry *dentry, const char *name)
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE; 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 * create entry for symbolic link in parent directory
...@@ -1151,7 +1154,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1151,7 +1154,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} }
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_DELETE; tblk->xflag |= COMMIT_DELETE;
tblk->ip = new_ip; tblk->u.ip = new_ip;
} else if (new_ip->i_nlink == 0) { } else if (new_ip->i_nlink == 0) {
assert(!test_cflag(COMMIT_Nolink, new_ip)); assert(!test_cflag(COMMIT_Nolink, new_ip));
/* free block resources */ /* free block resources */
...@@ -1162,7 +1165,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1162,7 +1165,7 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} }
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_DELETE; tblk->xflag |= COMMIT_DELETE;
tblk->ip = new_ip; tblk->u.ip = new_ip;
} else { } else {
new_ip->i_ctime = CURRENT_TIME; new_ip->i_ctime = CURRENT_TIME;
mark_inode_dirty(new_ip); mark_inode_dirty(new_ip);
...@@ -1347,7 +1350,8 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) ...@@ -1347,7 +1350,8 @@ int jfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE; tblk->xflag |= COMMIT_CREATE;
tblk->ip = ip; tblk->ino = ip->i_ino;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
ino = ip->i_ino; ino = ip->i_ino;
if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) 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