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