[CHECKER] Transcation is not fully aborted upon failure in JFS (jfs2.4, kernel 2.4.19)

From: Junfeng Yang
Date: Tue Apr 27 2004 - 01:56:33 EST


Hi,

We checked JFS filesystem on linux 2.4.19 recently and found 1 case that
looks like bugs.

When doing jfs_rename, if dtDelete fails, the transaction won't be fully
aborted (even if txAbort is called).

The symptoms are either we can read the new entry in the new dir by
getdents, but we can't actually open the file (always get -ENOENTs), or
after we do a sync, we see the new entry which is not supposed to be there
(since the transcation is aborted already). I couldn't figure out why
this is happening.

---------------------------------------------------------------------
[BUG] Transaction is not fully aborted even if txAbort is called when
dtDelete failed. dtDelete will return error if kmalloc fails at
'jfs_dtree.c:dtSearch:586 jfs_dtree.c:dtDelete:2066'

/*
* NAME: jfs_rename
*
* FUNCTION: rename a file or directory
*/
int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
...
/*
* Add new directory entry
*/
rc = dtSearch(new_dir, &new_dname, &ino, &btstack,
JFS_CREATE);
if (rc) {
jfs_err("jfs_rename didn't expect dtSearch to fail "
"w/rc = %d", rc);
goto out4;
}

ino = old_ip->i_ino;
rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
if (rc) {
jfs_err("jfs_rename: dtInsert failed w/rc = %d",
rc);
goto out4;
}

if (S_ISDIR(old_ip->i_mode))
new_dir->i_nlink++;
}
/*
* Remove old directory entry
*/

ino = old_ip->i_ino;
FAIL--> rc = dtDelete(tid, old_dir, &old_dname, &ino, JFS_REMOVE);
if (rc) {
jfs_err("jfs_rename did not expect dtDelete to return rc = %d",
rc);
ERROR--> txAbort(tid, 1); /* Marks Filesystem dirty */
goto out4;
}
...
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/