1 #ifndef lint 2 static char version[] = "@(#)pass5.c 3.3 (Berkeley) 01/10/85"; 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 (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 40 blk = blkmap(&sblock, cgrp.cg_free, b); 41 if (blk == 0) 42 continue; 43 if (blk == blockbits) { 44 if (pass5check(cbase+b, sblock.fs_frag) == STOP) 45 goto out5; 46 /* this is clumsy ... */ 47 n_ffree -= sblock.fs_frag; 48 n_bfree++; 49 botot[cbtocylno(&sblock, b)]++; 50 bo[cbtocylno(&sblock, b)] 51 [cbtorpos(&sblock, b)]++; 52 continue; 53 } 54 for (d = 0; d < sblock.fs_frag; d++) 55 if ((blk & (1<<d)) && 56 pass5check(cbase + b + d, (long)1) == STOP) 57 goto out5; 58 fragacct(&sblock, blk, frsum, 1); 59 } 60 if (bcmp((char *)cgrp.cg_frsum, (char *)frsum, sizeof(frsum))) { 61 if (debug) 62 for (i = 0; i < sblock.fs_frag; i++) 63 if (cgrp.cg_frsum[i] != frsum[i]) 64 printf("cg[%d].cg_frsum[%d] have %d calc %d\n", 65 c, i, cgrp.cg_frsum[i], frsum[i]); 66 frsumbad++; 67 } 68 if (bcmp((char *)cgrp.cg_btot, (char *)botot, sizeof (botot))) { 69 if (debug) 70 for (n = 0; n < sblock.fs_cpg; n++) 71 if (botot[n] != cgrp.cg_btot[n]) 72 printf("cg[%d].cg_btot[%d] have %d calc %d\n", 73 c, n, cgrp.cg_btot[n], botot[n]); 74 offsumbad++; 75 } 76 if (bcmp((char *)cgrp.cg_b, (char *)bo, sizeof (bo))) { 77 if (debug) 78 for (i = 0; i < NRPOS; i++) 79 if (bo[n][i] != cgrp.cg_b[n][i]) 80 printf("cg[%d].cg_b[%d][%d] have %d calc %d\n", 81 c, n, i, cgrp.cg_b[n][i], bo[n][i]); 82 offsumbad++; 83 } 84 } 85 out5: 86 if (dupblk) 87 pwarn("%d DUP BLKS IN BIT MAPS\n", dupblk); 88 if (fixcg == 0) { 89 if ((b = n_blks+n_ffree+sblock.fs_frag*n_bfree+n_index+n_bad) != fmax) { 90 pwarn("%ld BLK(S) MISSING\n", fmax - b); 91 fixcg = 1; 92 } else if (inosumbad + offsumbad + frsumbad + sbsumbad) { 93 pwarn("SUMMARY INFORMATION %s%s%s%sBAD\n", 94 inosumbad ? "(INODE FREE) " : "", 95 offsumbad ? "(BLOCK OFFSETS) " : "", 96 frsumbad ? "(FRAG SUMMARIES) " : "", 97 sbsumbad ? "(SUPER BLOCK SUMMARIES) " : ""); 98 fixcg = 1; 99 } else if (n_ffree != sblock.fs_cstotal.cs_nffree || 100 n_bfree != sblock.fs_cstotal.cs_nbfree) { 101 pwarn("FREE BLK COUNT(S) WRONG IN SUPERBLK"); 102 if (preen) 103 printf(" (FIXED)\n"); 104 if (preen || reply("FIX") == 1) { 105 sblock.fs_cstotal.cs_nffree = n_ffree; 106 sblock.fs_cstotal.cs_nbfree = n_bfree; 107 sbdirty(); 108 } 109 } 110 } 111 if (fixcg) { 112 pwarn("BAD CYLINDER GROUPS"); 113 if (preen) 114 printf(" (SALVAGED)\n"); 115 else if (reply("SALVAGE") == 0) 116 fixcg = 0; 117 } 118 } 119 120 pass5check(blk, size) 121 daddr_t blk; 122 long size; 123 { 124 125 if (outrange(blk, (int)size)) { 126 fixcg = 1; 127 if (preen) 128 pfatal("BAD BLOCKS IN BIT MAPS."); 129 if (++badblk >= MAXBAD) { 130 printf("EXCESSIVE BAD BLKS IN BIT MAPS."); 131 if (reply("CONTINUE") == 0) 132 errexit(""); 133 return (STOP); 134 } 135 } 136 for (; size > 0; blk++, size--) 137 if (getfmap(blk)) { 138 fixcg = 1; 139 ++dupblk; 140 } else { 141 n_ffree++; 142 setfmap(blk); 143 } 144 return (KEEPON); 145 } 146