Bug 866
Summary: | BUG at fs/jfs/namei.c:492 assert(!test_cflag(COMMIT_Nolink, ip)) | ||
---|---|---|---|
Product: | File System | Reporter: | Robbie Williamson (robbiew) |
Component: | JFS | Assignee: | Dave Kleikamp (shaggy) |
Status: | CLOSED CODE_FIX | ||
Severity: | normal | CC: | sglass |
Priority: | P2 | ||
Hardware: | i386 | ||
OS: | Linux | ||
Kernel Version: | 2.5.73 | Subsystem: | |
Regression: | --- | Bisected commit-id: | |
Attachments: |
File System race tester script
Patch to disallow link to a file with i_nlink == 0 |
Description
Robbie Williamson
2003-07-02 12:09:32 UTC
I'm a complete newbie at this so I could be wrong. It seems like in jfs_rename() ... 1271 if (new_ip && (new_ip->i_nlink == 0)) 1272 set_cflag(COMMIT_Nolink, new_ip); ... should be under lock but new_ip is unlocked. 1256 if (new_ip) 1257 up(&JFS_IP(new_ip)->commit_sem); 1258 1259 while (new_size && (rc == 0)) { 1260 tid = txBegin(new_ip->i_sb, 0); 1261 down(&JFS_IP(new_ip)->commit_sem); 1262 new_size = xtTruncate_pmap(tid, new_ip, new_size); 1263 if (new_size < 0) { 1264 txAbort(tid, 1); 1265 rc = -new_size; /* We return -rc */ 1266 } else 1267 rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC); 1268 txEnd(tid); 1269 up(&JFS_IP(new_ip)->commit_sem); 1270 } 1271 if (new_ip && (new_ip->i_nlink == 0)) 1272 set_cflag(COMMIT_Nolink, new_ip); i_sem is held during rename and unlink, so I don't think there is a problem with the inode being unlocked in this code. That said, there must be a race in the code somewhere for you to get this error. Created attachment 480 [details]
File System race tester script
(still learning how bugzilla works) I added an attachment which is a small script that can be used to trigger the bug within a minute or two. zcat racer.tar.gz cd racer ./racer.sh It uses files in racer/race/ to try create race situations. Created attachment 1287 [details]
Patch to disallow link to a file with i_nlink == 0
Sorry for sitting on this one so long.
There is a race where unlink can decrement i_nlink to zero, and then link() can
increment it back to 1. The unlink code only expects the link count to go to
zero once. The fix is to have link() fail if i_nlink was previously zero.
|