Date: Wed, 29 Apr 1998 21:50:01 -0700 (PDT) From: Luoqi Chen <luoqi@chen.ml.org> To: freebsd-bugs Subject: Re: kern/6274: panic: handle_workitem_freeblocks: block count (softupdates) Message-ID: <199804300450.VAA02245@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/6274; it has been noted by GNATS. From: Luoqi Chen <luoqi@chen.ml.org> To: freebsd-gnats-submit@freebsd.org, pst@Shockwave.COM Cc: Subject: Re: kern/6274: panic: handle_workitem_freeblocks: block count (softupdates) Date: Thu, 30 Apr 1998 00:43:15 -0400 I have a pretty good idea of what have happened and a fix. It was caused by a vinvalbuf() being mistakenly replaced by vtruncbuf() in function ffs_ftruncate(). Here is the diff, Index: ffs_inode.c =================================================================== RCS file: /fun/cvs/src/sys/ufs/ffs/ffs_inode.c,v retrieving revision 1.40 diff -u -r1.40 ffs_inode.c --- ffs_inode.c 1998/03/30 09:55:55 1.40 +++ ffs_inode.c 1998/04/23 21:15:22 @@ -212,7 +212,7 @@ (void) chkdq(oip, -oip->i_blocks, NOCRED, 0); #endif softdep_setup_freeblocks(oip, length); - (void) vtruncbuf(ovp, cred, p, length, fs->fs_bsize); + (void) vinvalbuf(ovp, 0, cred, p, 0, 0); oip->i_flag |= IN_CHANGE | IN_UPDATE; return (ffs_update(ovp, &tv, &tv, 0)); } This portion of code is executed when a file is truncated to zero length. vtruncbuf() only invalidates all the cached data bufs but none of the meta data ones. This will cause a serious problem when the file is extended immediately. The first 12 direct blocks should be allocated fine, but before the 13th block is allocated, the first indirect block is allocated (lblkno = -12). Since we have a valid cached buf for this indirect block, it will be reused, and NOT be zeroed (because it is clean). Now that the direct block pointers in the indirect block are not zero, they will be reused too even though they are marked free in cylinder group's bitmap. The next time you truncate this file down to zero size, you will get a "freeing free block" panic, or in the case those free blocks have been allocated to other files AND you didn't extend the file to its original size, you would have freed more blocks than expected, thus the "block count" panic. vinvalbuf() on the other hands invalidates all bufs associated with this file, data and meta-data alike. The reason that vinvalbuf() was replaced by vtruncbuf() is that vtruncbuf() would not cause unnecessary sync operations. But the case that the file is truncated to zero size, vinvalbuf() will discard all bufs and therefore will not cause any sync either. So switch back to vinvalbuf() is the correct solution. In the non-softupdate case, replacing vinvalbuf() with vtruncbuf() will not cause similar problem, because these indirect blocks are subsequently freed synchonously. I have communicated this to John Dyson about a week ago, but haven't got any response from him yet (thrown away by anti-spam filter?). I hope this fix could be committed soon. This seems to be the last bug in the softupdate code -- it has been rock solid for me since the fix. -lq To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804300450.VAA02245>