Skip site navigation (1)Skip section navigation (2)
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>