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>
index | next in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804300450.VAA02245>
