Commit 00746b1f authored by Dave Kleikamp's avatar Dave Kleikamp

JFS: fix race in jfs_commit_inode

There was a race that resulted in old, deleted inodes being written
to disk after the inode number had been reused.  jfs_commit_inode
needs to verify that the inode is still linked and dirty before
committing it.
Signed-off-by: default avatarDave Kleikamp <shaggy@austin.ibm.com>
parent ad54da3a
...@@ -81,8 +81,7 @@ int jfs_commit_inode(struct inode *inode, int wait) ...@@ -81,8 +81,7 @@ int jfs_commit_inode(struct inode *inode, int wait)
* Don't commit if inode has been committed since last being * Don't commit if inode has been committed since last being
* marked dirty, or if it has been deleted. * marked dirty, or if it has been deleted.
*/ */
if (test_cflag(COMMIT_Nolink, inode) || if (inode->i_nlink == 0 || !test_cflag(COMMIT_Dirty, inode))
!test_cflag(COMMIT_Dirty, inode))
return 0; return 0;
if (isReadOnly(inode)) { if (isReadOnly(inode)) {
...@@ -100,7 +99,13 @@ int jfs_commit_inode(struct inode *inode, int wait) ...@@ -100,7 +99,13 @@ int jfs_commit_inode(struct inode *inode, int wait)
tid = txBegin(inode->i_sb, COMMIT_INODE); tid = txBegin(inode->i_sb, COMMIT_INODE);
down(&JFS_IP(inode)->commit_sem); down(&JFS_IP(inode)->commit_sem);
rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
/*
* Retest inode state after taking commit_sem
*/
if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
txEnd(tid); txEnd(tid);
up(&JFS_IP(inode)->commit_sem); up(&JFS_IP(inode)->commit_sem);
return rc; return rc;
......
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