Annotation of src/sbin/fsck_lfs/pass5.c, Revision 1.9.2.1
1.9.2.1 ! tv 1: /* $NetBSD$ */
1.4 perseant 2:
3: /*-
4: * Copyright (c) 2000 The NetBSD Foundation, Inc.
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:
39: #include <sys/param.h>
40: #include <sys/time.h>
41: #include <ufs/ufs/dinode.h>
1.3 perseant 42: #include <ufs/ufs/dir.h>
43: #include <sys/mount.h>
44: #include <ufs/lfs/lfs.h>
1.9.2.1 ! tv 45: #include <ufs/lfs/lfs_extern.h>
1.3 perseant 46:
1.1 perseant 47: #include <string.h>
48: #include "fsck.h"
49: #include "extern.h"
1.3 perseant 50: #include "fsutil.h"
51:
1.4 perseant 52: extern SEGUSE *seg_table;
1.1 perseant 53:
54: void
55: pass5()
56: {
1.4 perseant 57: SEGUSE *su;
1.3 perseant 58: struct bufarea *bp;
1.4 perseant 59: int i;
1.6 perseant 60: unsigned long bb; /* total number of used blocks (lower bound) */
61: unsigned long ubb; /* upper bound number of used blocks */
62: unsigned long avail; /* blocks available for writing */
1.8 perseant 63: unsigned long dmeta; /* blocks in segsums and inodes */
1.7 perseant 64: int nclean; /* clean segments */
1.9 perseant 65: size_t labelskew;
1.3 perseant 66:
67: /*
68: * Check segment holdings against actual holdings. Check for
69: * "clean" segments that contain live data.
70: */
1.7 perseant 71: nclean = 0;
1.6 perseant 72: avail = 0;
73: bb = ubb = 0;
1.8 perseant 74: dmeta = 0;
1.4 perseant 75: for (i = 0; i < sblock.lfs_nseg; i++) {
1.3 perseant 76: su = lfs_gseguse(i, &bp);
77: if (!(su->su_flags & SEGUSE_DIRTY) &&
1.4 perseant 78: seg_table[i].su_nbytes > 0) {
1.3 perseant 79: pwarn("%d bytes contained in 'clean' segment %d\n",
80: seg_table[i].su_nbytes, i);
1.4 perseant 81: if (preen || reply("fix")) {
1.3 perseant 82: su->su_flags |= SEGUSE_DIRTY;
83: dirty(bp);
84: }
85: }
86: if ((su->su_flags & SEGUSE_DIRTY) &&
1.4 perseant 87: su->su_nbytes != seg_table[i].su_nbytes) {
1.5 perseant 88: pwarn("segment %d claims %d bytes but has %d",
1.3 perseant 89: i, su->su_nbytes, seg_table[i].su_nbytes);
1.5 perseant 90: if (su->su_nbytes > seg_table[i].su_nbytes)
91: pwarn(" (high by %d)\n", su->su_nbytes -
92: seg_table[i].su_nbytes);
93: else
94: pwarn(" (low by %d)\n", - su->su_nbytes +
95: seg_table[i].su_nbytes);
1.4 perseant 96: if (preen || reply("fix")) {
1.3 perseant 97: su->su_nbytes = seg_table[i].su_nbytes;
98: dirty(bp);
1.1 perseant 99: }
100: }
1.6 perseant 101: if (su->su_flags & SEGUSE_DIRTY) {
1.9 perseant 102: bb += btofsb(&sblock, su->su_nbytes +
103: su->su_nsums * sblock.lfs_sumsize);
104: ubb += btofsb(&sblock, su->su_nbytes +
105: su->su_nsums * sblock.lfs_sumsize +
106: su->su_ninos * sblock.lfs_ibsize);
107: dmeta += btofsb(&sblock,
108: sblock.lfs_sumsize * su->su_nsums);
109: dmeta += btofsb(&sblock,
110: sblock.lfs_ibsize * su->su_ninos);
1.6 perseant 111: } else {
1.7 perseant 112: nclean++;
1.9 perseant 113: avail += segtod(&sblock, 1);
1.6 perseant 114: if (su->su_flags & SEGUSE_SUPERBLOCK)
1.9 perseant 115: avail -= btofsb(&sblock, LFS_SBPAD);
116: if (i == 0 && sblock.lfs_version > 1 &&
117: sblock.lfs_start < btofsb(&sblock, LFS_LABELPAD))
118: avail -= btofsb(&sblock, LFS_LABELPAD) -
119: sblock.lfs_start;
1.6 perseant 120: }
1.3 perseant 121: bp->b_flags &= ~B_INUSE;
1.6 perseant 122: }
123: /* Also may be available bytes in current seg */
1.9 perseant 124: i = dtosn(&sblock, sblock.lfs_offset);
125: avail += sntod(&sblock, i + 1) - sblock.lfs_offset;
1.6 perseant 126: /* But do not count minfreesegs */
1.9 perseant 127: avail -= segtod(&sblock, (sblock.lfs_minfreeseg -
128: (sblock.lfs_minfreeseg / 2)));
1.6 perseant 129:
1.8 perseant 130: if (dmeta != sblock.lfs_dmeta) {
131: pwarn("dmeta given as %d, should be %ld\n", sblock.lfs_dmeta,
132: dmeta);
133: if (preen || reply("fix")) {
134: sblock.lfs_dmeta = dmeta;
135: sbdirty();
136: }
137: }
1.6 perseant 138: if (avail != sblock.lfs_avail) {
139: pwarn("avail given as %d, should be %ld\n", sblock.lfs_avail,
140: avail);
141: if (preen || reply("fix")) {
142: sblock.lfs_avail = avail;
1.7 perseant 143: sbdirty();
144: }
145: }
146: if (nclean != sblock.lfs_nclean) {
147: pwarn("nclean given as %d, should be %d\n", sblock.lfs_nclean,
148: nclean);
149: if (preen || reply("fix")) {
150: sblock.lfs_nclean = nclean;
1.6 perseant 151: sbdirty();
152: }
153: }
1.9 perseant 154: labelskew = (sblock.lfs_version == 1 ? 0 :
155: btofsb(&sblock, LFS_LABELPAD));
156: if (sblock.lfs_bfree > sblock.lfs_dsize - bb - labelskew ||
157: sblock.lfs_bfree < sblock.lfs_dsize - ubb - labelskew) {
1.6 perseant 158: pwarn("bfree given as %d, should be between %ld and %ld\n",
1.9 perseant 159: sblock.lfs_bfree, sblock.lfs_dsize - ubb - labelskew,
160: sblock.lfs_dsize - bb - labelskew);
1.6 perseant 161: if (preen || reply("fix")) {
1.9 perseant 162: sblock.lfs_bfree = sblock.lfs_dsize - labelskew -
163: (ubb + bb) / 2;
1.6 perseant 164: sbdirty();
165: }
1.1 perseant 166: }
167: }
CVSweb <webmaster@jp.NetBSD.org>