Subject: bin/11534: fsck_lfs doesn't check and/or fix lfs_dmeta in LFS superblock
To: None <gnats-bugs@gnats.netbsd.org>
From: None <joff@gci-net.com>
List: netbsd-bugs
Date: 11/20/2000 20:07:13
>Number:         11534
>Category:       bin
>Synopsis:       fsck_lfs doesn't check and/or fix lfs_dmeta in LFS superblock
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Nov 20 20:07:00 PST 2000
>Closed-Date:
>Last-Modified:
>Originator:     Jesse Off
>Release:        1.5BETA2
>Organization:
>Environment:
NetBSD construct.home 1.5_BETA NetBSD 1.5_BETA (CONSTRUCT) #27: Sun Nov 19 19:53:59 MST 2000     root@construct.home:/usr/src/sys/arch/i386/compile/CONSTRUCT i386
>Description:
fsck_lfs doesn't check lfs_dmeta (disk blocks allocated to segment 
summaries and inode blocks) and fix the bad count.  I've enclosed a patch
that fixes this.  When this happens, sys_statfs() can return incorrect
disk usage estimates to 'df'.
>How-To-Repeat:

>Fix:
Apply the following patch:

RCS file: /cvsroot/basesrc/sbin/fsck_lfs/pass5.c,v
retrieving revision 1.7
diff -u -r1.7 pass5.c
--- pass5.c     2000/11/13 00:30:48     1.7
+++ pass5.c     2000/11/21 04:03:23
@@ -1,4 +1,4 @@
-/* $NetBSD: pass5.c,v 1.7 2000/11/13 00:30:48 perseant Exp $    */
+/* $NetBSD: pass5.c,v 1.5.2.1 2000/09/14 18:53:21 perseant Exp $        */
 
 /*-
  * Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -59,7 +59,8 @@
        unsigned long   bb; /* total number of used blocks (lower bound) */
        unsigned long   ubb; /* upper bound number of used blocks */
        unsigned long   avail; /* blocks available for writing */
-       int             nclean; /* clean segments */
+       unsigned long   dmeta; /* blocks in segsums and inodes */
+       int             nclean; /* clean segments */
 
        /*
         * Check segment holdings against actual holdings.  Check for
@@ -68,6 +69,7 @@
        nclean = 0;
        avail = 0;
        bb = ubb = 0;
+       dmeta = 0;
        for (i = 0; i < sblock.lfs_nseg; i++) {
                su = lfs_gseguse(i, &bp);
                if (!(su->su_flags & SEGUSE_DIRTY) &&
@@ -97,6 +99,8 @@
                if (su->su_flags & SEGUSE_DIRTY) {
                        bb += btodb(su->su_nbytes) + su->su_nsums;
                        ubb += btodb(su->su_nbytes) + su->su_nsums + fsbtodb(&sblock, su->su_ninos);
+                       dmeta += btodb(LFS_SUMMARY_SIZE * su->su_nsums);
+                       dmeta += fsbtodb(&sblock, su->su_ninos); 
                } else {
                        nclean++;
                        avail += fsbtodb(&sblock, sblock.lfs_ssize);
@@ -112,6 +116,14 @@
        avail -= fsbtodb(&sblock, sblock.lfs_ssize) *
                (sblock.lfs_minfreeseg - (sblock.lfs_minfreeseg / 2));
 
+       if (dmeta != sblock.lfs_dmeta) {
+               pwarn("dmeta given as %d, should be %ld\n", sblock.lfs_dmeta,
+                     dmeta);
+               if (preen || reply("fix")) {
+                       sblock.lfs_dmeta = dmeta;
+                       sbdirty();
+               }
+       }
        if (avail != sblock.lfs_avail) {
                pwarn("avail given as %d, should be %ld\n", sblock.lfs_avail,
                      avail);



>Release-Note:
>Audit-Trail:
>Unformatted: