Subject: kern/9994: combination of ftruncate() and lseek() can cause LFS panic
To: None <gnats-bugs@gnats.netbsd.org>
From: IWAMOTO Toshihiro <iwamoto@sat.t.u-tokyo.ac.jp>
List: netbsd-bugs
Date: 04/27/2000 08:48:17
>Number: 9994
>Category: kern
>Synopsis: combination of ftruncate() and lseek() can cause LFS panic
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Apr 27 08:49:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator: IWAMOTO Toshihiro
>Release: today's -current
>Organization:
>Environment:
System: NetBSD miyuki.my.domain 1.4X NetBSD 1.4X (MASH) #45: Thu Apr 27 23:33:06 JST 2000 toshii@miyuki.my.domain:/usr/src/syssrc/sys/arch/i386/compile/MASH i386
>Description:
Intense inode changes can cause inconsistency of LFS.
Here is a ten-finger copy of a panic. This problem should not
be related to recent fixes to PR #9926, as older versions of lfs_*.c
also cause panics.
# cc test.c (the attached test program)
# ./a.out
lfs_inode: 32 frags released > 25 in inode 6
lfs_inode: 64 frags released > 63 in inode 6
lfs_inode: 40 frags released > 28 in inode 6
panic: lfs_truncate: frag count < 0 (144<244), ino 6
Stopped in a.out at cpu_Debugger+0x4: leave
db> tr
cpu_Debugger(...) at cpu_Debugger+0x4
panic(...) at panic+0x55
lfs_truncate(c7b5ce80) at lfs_truncate+0x1200
ufs_setattr(c7b5cebc,c7b5cf88,c797976c,c7b5cf80,c7b5cf88) at ufs_setattr+0x1d4
sys_ftruncate(c797976c,c7b5cf88,c7b5cf80,0,4ed7) at sys_ftruncate+0xfd
syscall() at syscall+0x1ed
>How-To-Repeat:
Execute the following code. The system will panic in seconds.
I didn't confirmed if any of read(), write() or usleep() can be
omitted to invoke kernel panics.
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char** argv) {
char hoge[8192], buf[8192];
int fd, i, j, k;
for(i=0; i<sizeof(hoge); i++)
hoge[i] = (i / 7) & 0xff;
sprintf(buf, "test.%d", getpid());
unlink(buf);
fd = open(buf, O_RDWR | O_CREAT, 0644);
if (fd < 0) {
perror("open");
exit(1);
}
srandom(time(0));
for(i=0; i<10000; i++) {
j = random() % 3;
k = random() & 0x3fffff;
if (j != 2)
if (lseek(fd, k, SEEK_SET) < 0) {
perror("read");
exit(1);
}
switch(j) {
case 0:
if (read(fd, buf, sizeof(buf)) < 0) {
perror("read");
exit(1);
}
break;
case 1:
if (write(fd, hoge, sizeof(hoge)) < 0) {
perror("write");
exit(1);
}
break;
case 2:
if (ftruncate(fd, k) < 0) {
perror("write");
exit(1);
}
break;
}
j = random() % 100*1000;
usleep(j);
}
exit(0);
}
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: