Commit 6a3ecb7a authored by Dave Kleikamp's avatar Dave Kleikamp

JFS: Yet another truncation fix.

In the case where a large truncate requires multiple transactions,
we were setting the COMMIT_Nolink flag too early, causing an
assert to fire during the next transaction in the sequence.
parent 00601079
...@@ -1225,11 +1225,10 @@ int txCommit(tid_t tid, /* transaction identifier */ ...@@ -1225,11 +1225,10 @@ int txCommit(tid_t tid, /* transaction identifier */
*/ */
if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE)) if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE))
atomic_inc(&tblk->ip->i_count); atomic_inc(&tblk->ip->i_count);
if (tblk->xflag & COMMIT_DELETE) {
ip = tblk->ip; ASSERT((!(tblk->xflag & COMMIT_DELETE)) ||
assert((ip->i_nlink == 0) && !test_cflag(COMMIT_Nolink, ip)); ((tblk->ip->i_nlink == 0) &&
set_cflag(COMMIT_Nolink, ip); !test_cflag(COMMIT_Nolink, tblk->ip)));
}
/* /*
* write COMMIT log record * write COMMIT log record
......
...@@ -528,6 +528,9 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -528,6 +528,9 @@ int jfs_unlink(struct inode *dip, struct dentry *dentry)
txEnd(tid); txEnd(tid);
} }
if (ip->i_nlink == 0)
set_cflag(COMMIT_Nolink, ip);
if (!test_cflag(COMMIT_Holdlock, ip)) if (!test_cflag(COMMIT_Holdlock, ip))
IWRITE_UNLOCK(ip); IWRITE_UNLOCK(ip);
...@@ -1273,6 +1276,8 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1273,6 +1276,8 @@ int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC); rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
txEnd(tid); txEnd(tid);
} }
if (new_ip && (new_ip->i_nlink == 0))
set_cflag(COMMIT_Nolink, new_ip);
out3: out3:
free_UCSname(&new_dname); free_UCSname(&new_dname);
out2: out2:
......
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