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>