xref: /csrg-svn/sbin/fsck/pass5.c (revision 16848)
1 #ifndef lint
2 static char version[] = "@(#)pass5.c	3.2 (Berkeley) 08/06/84";
3 #endif
4 
5 #include <sys/param.h>
6 #include <sys/inode.h>
7 #include <sys/fs.h>
8 #include "fsck.h"
9 
10 pass5()
11 {
12 	register int c, n, i, b, d;
13 	short bo[MAXCPG][NRPOS];
14 	long botot[MAXCPG];
15 	long frsum[MAXFRAG];
16 	int blk;
17 	daddr_t cbase;
18 	int blockbits = (1<<sblock.fs_frag)-1;
19 
20 	bcopy(blockmap, freemap, (unsigned)bmapsz);
21 	dupblk = 0;
22 	n_index = sblock.fs_ncg * (cgdmin(&sblock, 0) - cgtod(&sblock, 0));
23 	for (c = 0; c < sblock.fs_ncg; c++) {
24 		cbase = cgbase(&sblock, c);
25 		bzero((char *)botot, sizeof (botot));
26 		bzero((char *)bo, sizeof (bo));
27 		bzero((char *)frsum, sizeof (frsum));
28 		/*
29 		 * need to account for the super blocks
30 		 * which appear (inaccurately) bad
31 		 */
32 		n_bad += cgtod(&sblock, c) - cgsblock(&sblock, c);
33 		if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0)
34 			continue;
35 		if (cgrp.cg_magic != CG_MAGIC) {
36 			pfatal("CG %d: BAD MAGIC NUMBER\n", c);
37 			bzero((char *)&cgrp, (int)sblock.fs_cgsize);
38 		}
39 		for (i = 0, n = 0; i < sblock.fs_ipg; i += NBBY, n++)
40 			if (cgrp.cg_iused[n] != 0xff)
41 				break;
42 		for ( ; i < sblock.fs_ipg; i++) {
43 			if (isclr(cgrp.cg_iused, i)) {
44 				if (i < cgrp.cg_irotor) {
45 					if (debug) printf(
46 					    "cg %d, first free %d, irotor %d\n",
47 					     c, i, cgrp.cg_irotor);
48 					cgrp.cg_irotor = i;
49 					cgdirty();
50 					break;
51 				}
52 			}
53 		}
54 		for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
55 			blk = blkmap(&sblock, cgrp.cg_free, b);
56 			if (blk == 0)
57 				continue;
58 			if (blk == blockbits) {
59 				if (pass5check(cbase+b, sblock.fs_frag) == STOP)
60 					goto out5;
61 				/* this is clumsy ... */
62 				n_ffree -= sblock.fs_frag;
63 				n_bfree++;
64 				botot[cbtocylno(&sblock, b)]++;
65 				bo[cbtocylno(&sblock, b)]
66 				    [cbtorpos(&sblock, b)]++;
67 				continue;
68 			}
69 			for (d = 0; d < sblock.fs_frag; d++)
70 				if ((blk & (1<<d)) &&
71 				    pass5check(cbase + b + d, (long)1) == STOP)
72 					goto out5;
73 			fragacct(&sblock, blk, frsum, 1);
74 		}
75 		if (bcmp((char *)cgrp.cg_frsum, (char *)frsum, sizeof(frsum))) {
76 			if (debug)
77 			for (i = 0; i < sblock.fs_frag; i++)
78 				if (cgrp.cg_frsum[i] != frsum[i])
79 				printf("cg[%d].cg_frsum[%d] have %d calc %d\n",
80 				    c, i, cgrp.cg_frsum[i], frsum[i]);
81 			frsumbad++;
82 		}
83 		if (bcmp((char *)cgrp.cg_btot, (char *)botot, sizeof (botot))) {
84 			if (debug)
85 			for (n = 0; n < sblock.fs_cpg; n++)
86 				if (botot[n] != cgrp.cg_btot[n])
87 				printf("cg[%d].cg_btot[%d] have %d calc %d\n",
88 				    c, n, cgrp.cg_btot[n], botot[n]);
89 			offsumbad++;
90 		}
91 		if (bcmp((char *)cgrp.cg_b, (char *)bo, sizeof (bo))) {
92 			if (debug)
93 			for (i = 0; i < NRPOS; i++)
94 				if (bo[n][i] != cgrp.cg_b[n][i])
95 				printf("cg[%d].cg_b[%d][%d] have %d calc %d\n",
96 				    c, n, i, cgrp.cg_b[n][i], bo[n][i]);
97 			offsumbad++;
98 		}
99 	}
100 out5:
101 	if (dupblk)
102 		pwarn("%d DUP BLKS IN BIT MAPS\n", dupblk);
103 	if (fixcg == 0) {
104 		if ((b = n_blks+n_ffree+sblock.fs_frag*n_bfree+n_index+n_bad) != fmax) {
105 			pwarn("%ld BLK(S) MISSING\n", fmax - b);
106 			fixcg = 1;
107 		} else if (inosumbad + offsumbad + frsumbad + sbsumbad) {
108 			pwarn("SUMMARY INFORMATION %s%s%s%sBAD\n",
109 			    inosumbad ? "(INODE FREE) " : "",
110 			    offsumbad ? "(BLOCK OFFSETS) " : "",
111 			    frsumbad ? "(FRAG SUMMARIES) " : "",
112 			    sbsumbad ? "(SUPER BLOCK SUMMARIES) " : "");
113 			fixcg = 1;
114 		} else if (n_ffree != sblock.fs_cstotal.cs_nffree ||
115 		    n_bfree != sblock.fs_cstotal.cs_nbfree) {
116 			pwarn("FREE BLK COUNT(S) WRONG IN SUPERBLK");
117 			if (preen)
118 				printf(" (FIXED)\n");
119 			if (preen || reply("FIX") == 1) {
120 				sblock.fs_cstotal.cs_nffree = n_ffree;
121 				sblock.fs_cstotal.cs_nbfree = n_bfree;
122 				sbdirty();
123 			}
124 		}
125 	}
126 	if (fixcg) {
127 		pwarn("BAD CYLINDER GROUPS");
128 		if (preen)
129 			printf(" (SALVAGED)\n");
130 		else if (reply("SALVAGE") == 0)
131 			fixcg = 0;
132 	}
133 }
134 
135 pass5check(blk, size)
136 	daddr_t blk;
137 	long size;
138 {
139 
140 	if (outrange(blk, (int)size)) {
141 		fixcg = 1;
142 		if (preen)
143 			pfatal("BAD BLOCKS IN BIT MAPS.");
144 		if (++badblk >= MAXBAD) {
145 			printf("EXCESSIVE BAD BLKS IN BIT MAPS.");
146 			if (reply("CONTINUE") == 0)
147 				errexit("");
148 			return (STOP);
149 		}
150 	}
151 	for (; size > 0; blk++, size--)
152 		if (getfmap(blk)) {
153 			fixcg = 1;
154 			++dupblk;
155 		} else {
156 			n_ffree++;
157 			setfmap(blk);
158 		}
159 	return (KEEPON);
160 }
161