1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)pass5.c 5.3 (Berkeley) 10/13/86"; 9 #endif not lint 10 11 #include <sys/param.h> 12 #include <sys/inode.h> 13 #include <sys/fs.h> 14 #include "fsck.h" 15 16 pass5() 17 { 18 int c, blk, frags, sumsize, mapsize; 19 daddr_t dbase, dmax, d; 20 register long i, j; 21 struct csum *cs; 22 time_t now; 23 struct csum cstotal; 24 struct inodesc idesc; 25 char buf[MAXBSIZE]; 26 register struct cg *newcg = (struct cg *)buf; 27 28 bzero((char *)newcg, sblock.fs_cgsize); 29 newcg->cg_magic = CG_MAGIC; 30 bzero((char *)&idesc, sizeof(struct inodesc)); 31 idesc.id_type = ADDR; 32 bzero((char *)&cstotal, sizeof(struct csum)); 33 sumsize = cgrp.cg_iused - (char *)(&cgrp); 34 mapsize = &cgrp.cg_free[howmany(sblock.fs_fpg, NBBY)] - 35 (u_char *)cgrp.cg_iused; 36 (void)time(&now); 37 for (c = 0; c < sblock.fs_ncg; c++) { 38 getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); 39 if (cgrp.cg_magic != CG_MAGIC) 40 pfatal("CG %d: BAD MAGIC NUMBER\n", c); 41 dbase = cgbase(&sblock, c); 42 dmax = dbase + sblock.fs_fpg; 43 if (dmax > sblock.fs_size) 44 dmax = sblock.fs_size; 45 if (now > cgrp.cg_time) 46 newcg->cg_time = cgrp.cg_time; 47 else 48 newcg->cg_time = now; 49 newcg->cg_cgx = c; 50 if (c == sblock.fs_ncg - 1) 51 newcg->cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 52 else 53 newcg->cg_ncyl = sblock.fs_cpg; 54 newcg->cg_niblk = sblock.fs_ipg; 55 newcg->cg_ndblk = dmax - dbase; 56 newcg->cg_cs.cs_ndir = 0; 57 newcg->cg_cs.cs_nffree = 0; 58 newcg->cg_cs.cs_nbfree = 0; 59 newcg->cg_cs.cs_nifree = sblock.fs_ipg; 60 if (cgrp.cg_rotor < newcg->cg_ndblk) 61 newcg->cg_rotor = cgrp.cg_rotor; 62 else 63 newcg->cg_rotor = 0; 64 if (cgrp.cg_frotor < newcg->cg_ndblk) 65 newcg->cg_frotor = cgrp.cg_frotor; 66 else 67 newcg->cg_frotor = 0; 68 if (cgrp.cg_irotor < newcg->cg_niblk) 69 newcg->cg_irotor = cgrp.cg_irotor; 70 else 71 newcg->cg_irotor = 0; 72 bzero((char *)newcg->cg_frsum, sizeof newcg->cg_frsum); 73 bzero((char *)newcg->cg_btot, sizeof newcg->cg_btot); 74 bzero((char *)newcg->cg_b, sizeof newcg->cg_b); 75 bzero((char *)newcg->cg_free, howmany(sblock.fs_fpg, NBBY)); 76 bzero((char *)newcg->cg_iused, howmany(sblock.fs_ipg, NBBY)); 77 j = sblock.fs_ipg * c; 78 for (i = 0; i < sblock.fs_ipg; j++, i++) { 79 switch (statemap[j]) { 80 81 case USTATE: 82 break; 83 84 case DSTATE: 85 case DCLEAR: 86 case DFOUND: 87 newcg->cg_cs.cs_ndir++; 88 /* fall through */ 89 90 case FSTATE: 91 case FCLEAR: 92 newcg->cg_cs.cs_nifree--; 93 setbit(newcg->cg_iused, i); 94 break; 95 96 default: 97 if (j < ROOTINO) 98 break; 99 errexit("BAD STATE %d FOR INODE I=%d", 100 statemap[j], j); 101 } 102 } 103 if (c == 0) 104 for (i = 0; i < ROOTINO; i++) { 105 setbit(newcg->cg_iused, i); 106 newcg->cg_cs.cs_nifree--; 107 } 108 for (i = 0, d = dbase; 109 d <= dmax - sblock.fs_frag; 110 d += sblock.fs_frag, i += sblock.fs_frag) { 111 frags = 0; 112 for (j = 0; j < sblock.fs_frag; j++) { 113 if (getbmap(d + j)) 114 continue; 115 setbit(newcg->cg_free, i + j); 116 frags++; 117 } 118 if (frags == sblock.fs_frag) { 119 newcg->cg_cs.cs_nbfree++; 120 j = cbtocylno(&sblock, i); 121 newcg->cg_btot[j]++; 122 newcg->cg_b[j][cbtorpos(&sblock, i)]++; 123 } else if (frags > 0) { 124 newcg->cg_cs.cs_nffree += frags; 125 blk = blkmap(&sblock, newcg->cg_free, i); 126 fragacct(&sblock, blk, newcg->cg_frsum, 1); 127 } 128 } 129 for (frags = d; d < dmax; d++) { 130 if (getbmap(d)) 131 continue; 132 setbit(newcg->cg_free, d - dbase); 133 newcg->cg_cs.cs_nffree++; 134 } 135 if (frags != d) { 136 #ifdef tahoe 137 /* tahoe compiler workaround */ 138 int x = frags - dbase; 139 blk = blkmap(&sblock, newcg->cg_free, x); 140 #else 141 blk = blkmap(&sblock, newcg->cg_free, (frags - dbase)); 142 #endif 143 fragacct(&sblock, blk, newcg->cg_frsum, 1); 144 } 145 cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 146 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 147 cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 148 cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 149 if (bcmp(newcg->cg_iused, cgrp.cg_iused, mapsize) != 0 && 150 dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { 151 bcopy(newcg->cg_iused, cgrp.cg_iused, mapsize); 152 cgdirty(); 153 } 154 if (bcmp((char *)newcg, (char *)&cgrp, sumsize) != 0 && 155 dofix(&idesc, "SUMMARY INFORMATION BAD")) { 156 bcopy((char *)newcg, (char *)&cgrp, sumsize); 157 cgdirty(); 158 } 159 cs = &sblock.fs_cs(&sblock, c); 160 if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 161 dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 162 bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 163 sbdirty(); 164 } 165 } 166 if (bcmp((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs) != 0 167 && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 168 bcopy((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs); 169 sblock.fs_ronly = 0; 170 sblock.fs_fmod = 0; 171 sbdirty(); 172 } 173 } 174