[BACK]Return to pass5.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / fsck_lfs

Annotation of src/sbin/fsck_lfs/pass5.c, Revision 1.21

1.21    ! perseant    1: /* $NetBSD: pass5.c,v 1.20 2006/08/13 22:18:09 bjh21 Exp $      */
1.4       perseant    2:
                      3: /*-
1.12      perseant    4:  * Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
1.4       perseant    5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Konrad E. Schroder <perseant@hhhh.org>.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *      This product includes software developed by the NetBSD
                     21:  *      Foundation, Inc. and its contributors.
                     22:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     23:  *    contributors may be used to endorse or promote products derived
                     24:  *    from this software without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     27:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     28:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     29:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     30:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     31:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     32:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     33:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     34:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     35:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     36:  * POSSIBILITY OF SUCH DAMAGE.
                     37:  */
1.1       perseant   38:
1.12      perseant   39: #include <sys/types.h>
1.1       perseant   40: #include <sys/param.h>
                     41: #include <sys/time.h>
1.12      perseant   42: #include <sys/buf.h>
                     43: #include <sys/mount.h>
                     44:
                     45: #include <ufs/ufs/ufsmount.h>
                     46: #include <ufs/ufs/inode.h>
1.3       perseant   47: #include <ufs/ufs/dir.h>
1.12      perseant   48: #define vnode uvnode
1.3       perseant   49: #include <ufs/lfs/lfs.h>
1.12      perseant   50: #undef vnode
1.3       perseant   51:
1.1       perseant   52: #include <string.h>
1.12      perseant   53:
                     54: #include "bufcache.h"
                     55: #include "vnode.h"
1.17      christos   56: #include "lfs_user.h"
1.12      perseant   57:
1.1       perseant   58: #include "fsck.h"
                     59: #include "extern.h"
1.3       perseant   60: #include "fsutil.h"
                     61:
1.12      perseant   62: extern SEGUSE *seg_table;
                     63: extern off_t locked_queue_bytes;
1.1       perseant   64:
                     65: void
1.14      xtraeme    66: pass5(void)
1.1       perseant   67: {
1.12      perseant   68:        SEGUSE *su;
1.13      yamt       69:        struct ubuf *bp;
1.12      perseant   70:        int i;
                     71:        unsigned long bb;       /* total number of used blocks (lower bound) */
                     72:        unsigned long ubb;      /* upper bound number of used blocks */
                     73:        unsigned long avail;    /* blocks available for writing */
                     74:        unsigned long dmeta;    /* blocks in segsums and inodes */
                     75:        int nclean;             /* clean segments */
                     76:        size_t labelskew;
                     77:        int diddirty;
1.3       perseant   78:
                     79:        /*
                     80:         * Check segment holdings against actual holdings.  Check for
1.16      perseant   81:         * "clean" segments that contain live data.  If we are only
                     82:         * rolling forward, we can't check the segment holdings, but
                     83:         * we can still check the cleanerinfo data.
1.3       perseant   84:         */
1.7       perseant   85:        nclean = 0;
1.6       perseant   86:        avail = 0;
                     87:        bb = ubb = 0;
1.8       perseant   88:        dmeta = 0;
1.12      perseant   89:        for (i = 0; i < fs->lfs_nseg; i++) {
                     90:                diddirty = 0;
                     91:                LFS_SEGENTRY(su, fs, i, bp);
1.16      perseant   92:                if (!preen && !(su->su_flags & SEGUSE_DIRTY) &&
1.4       perseant   93:                    seg_table[i].su_nbytes > 0) {
1.21    ! perseant   94:                        pwarn("CLEAN SEGMENT %d CONTAINS %d BYTES\n",
1.19      perseant   95:                            i, seg_table[i].su_nbytes);
1.18      perseant   96:                        if (reply("MARK SEGMENT DIRTY")) {
1.3       perseant   97:                                su->su_flags |= SEGUSE_DIRTY;
1.12      perseant   98:                                ++diddirty;
1.3       perseant   99:                        }
                    100:                }
1.21    ! perseant  101:                if (!preen && su->su_nbytes != seg_table[i].su_nbytes) {
1.18      perseant  102:                        pwarn("SEGMENT %d CLAIMS %d BYTES BUT HAS %d",
1.12      perseant  103:                            i, su->su_nbytes, seg_table[i].su_nbytes);
                    104:                        if ((int32_t)su->su_nbytes >
                    105:                            (int32_t)seg_table[i].su_nbytes)
1.18      perseant  106:                                pwarn(" (HIGH BY %d)\n", su->su_nbytes -
1.12      perseant  107:                                    seg_table[i].su_nbytes);
1.5       perseant  108:                        else
1.18      perseant  109:                                pwarn(" (LOW BY %d)\n", -su->su_nbytes +
1.12      perseant  110:                                    seg_table[i].su_nbytes);
1.18      perseant  111:                        if (reply("FIX")) {
1.3       perseant  112:                                su->su_nbytes = seg_table[i].su_nbytes;
1.12      perseant  113:                                ++diddirty;
1.1       perseant  114:                        }
                    115:                }
1.6       perseant  116:                if (su->su_flags & SEGUSE_DIRTY) {
1.12      perseant  117:                        bb += btofsb(fs, su->su_nbytes +
                    118:                            su->su_nsums * fs->lfs_sumsize);
                    119:                        ubb += btofsb(fs, su->su_nbytes +
                    120:                            su->su_nsums * fs->lfs_sumsize +
                    121:                            su->su_ninos * fs->lfs_ibsize);
                    122:                        dmeta += btofsb(fs,
                    123:                            fs->lfs_sumsize * su->su_nsums);
                    124:                        dmeta += btofsb(fs,
                    125:                            fs->lfs_ibsize * su->su_ninos);
1.6       perseant  126:                } else {
1.7       perseant  127:                        nclean++;
1.12      perseant  128:                        avail += segtod(fs, 1);
1.6       perseant  129:                        if (su->su_flags & SEGUSE_SUPERBLOCK)
1.12      perseant  130:                                avail -= btofsb(fs, LFS_SBPAD);
                    131:                        if (i == 0 && fs->lfs_version > 1 &&
                    132:                            fs->lfs_start < btofsb(fs, LFS_LABELPAD))
                    133:                                avail -= btofsb(fs, LFS_LABELPAD) -
                    134:                                    fs->lfs_start;
1.6       perseant  135:                }
1.12      perseant  136:                if (diddirty)
                    137:                        VOP_BWRITE(bp);
                    138:                else
                    139:                        brelse(bp);
1.6       perseant  140:        }
1.12      perseant  141:
1.6       perseant  142:        /* Also may be available bytes in current seg */
1.12      perseant  143:        i = dtosn(fs, fs->lfs_offset);
                    144:        avail += sntod(fs, i + 1) - fs->lfs_offset;
1.6       perseant  145:        /* But do not count minfreesegs */
1.12      perseant  146:        avail -= segtod(fs, (fs->lfs_minfreeseg -
                    147:                (fs->lfs_minfreeseg / 2)));
                    148:        /* Note we may have bytes to write yet */
                    149:        avail -= btofsb(fs, locked_queue_bytes);
                    150:
1.15      perseant  151:        if (idaddr)
1.16      perseant  152:                pwarn("NOTE: when using -i, expect discrepancies in dmeta,"
                    153:                      " avail, nclean, bfree\n");
1.12      perseant  154:        if (dmeta != fs->lfs_dmeta) {
1.18      perseant  155:                pwarn("DMETA GIVEN AS %d, SHOULD BE %ld\n", fs->lfs_dmeta,
1.12      perseant  156:                    dmeta);
1.18      perseant  157:                if (preen || reply("FIX")) {
1.12      perseant  158:                        fs->lfs_dmeta = dmeta;
                    159:                        sbdirty();
                    160:                }
1.8       perseant  161:        }
1.13      yamt      162:        if (avail != fs->lfs_avail) {
1.20      bjh21     163:                pwarn("AVAIL GIVEN AS %d, SHOULD BE %ld\n", fs->lfs_avail,
1.12      perseant  164:                    avail);
1.18      perseant  165:                if (preen || reply("FIX")) {
1.12      perseant  166:                        fs->lfs_avail = avail;
1.7       perseant  167:                        sbdirty();
                    168:                }
                    169:        }
1.12      perseant  170:        if (nclean != fs->lfs_nclean) {
1.20      bjh21     171:                pwarn("NCLEAN GIVEN AS %d, SHOULD BE %d\n", fs->lfs_nclean,
1.12      perseant  172:                    nclean);
1.18      perseant  173:                if (preen || reply("FIX")) {
1.12      perseant  174:                        fs->lfs_nclean = nclean;
1.6       perseant  175:                        sbdirty();
                    176:                }
                    177:        }
1.12      perseant  178:
1.11      perseant  179:        labelskew = 0;
1.12      perseant  180:        if (fs->lfs_version > 1 &&
                    181:            fs->lfs_start < btofsb(fs, LFS_LABELPAD))
                    182:                labelskew = btofsb(fs, LFS_LABELPAD);
                    183:        if (fs->lfs_bfree > fs->lfs_dsize - bb - labelskew ||
                    184:            fs->lfs_bfree < fs->lfs_dsize - ubb - labelskew) {
1.18      perseant  185:                pwarn("BFREE GIVEN AS %d, SHOULD BE BETWEEN %ld AND %ld\n",
                    186:                    fs->lfs_bfree, MAX(0, fs->lfs_dsize - ubb - labelskew),
1.12      perseant  187:                    fs->lfs_dsize - bb - labelskew);
1.18      perseant  188:                if (preen || reply("FIX")) {
                    189:                        fs->lfs_bfree =
                    190:                                (MAX(0, fs->lfs_dsize - labelskew - ubb) +
                    191:                                 fs->lfs_dsize - labelskew - bb) / 2;
1.6       perseant  192:                        sbdirty();
                    193:                }
1.1       perseant  194:        }
                    195: }

CVSweb <webmaster@jp.NetBSD.org>