116267Smckusick #ifndef lint 2*17937Smckusick static char version[] = "@(#)pass5.c 3.4 (Berkeley) 02/08/85"; 316267Smckusick #endif 416267Smckusick 516267Smckusick #include <sys/param.h> 616267Smckusick #include <sys/inode.h> 716267Smckusick #include <sys/fs.h> 816267Smckusick #include "fsck.h" 916267Smckusick 1016267Smckusick pass5() 1116267Smckusick { 12*17937Smckusick int c, blk, frags, sumsize, mapsize; 13*17937Smckusick daddr_t dbase, dmax, d; 14*17937Smckusick register long i, j; 15*17937Smckusick struct csum *cs; 16*17937Smckusick time_t now; 17*17937Smckusick struct csum cstotal; 18*17937Smckusick struct inodesc idesc; 19*17937Smckusick char buf[MAXBSIZE]; 20*17937Smckusick register struct cg *newcg = (struct cg *)buf; 2116267Smckusick 22*17937Smckusick bzero((char *)newcg, sblock.fs_cgsize); 23*17937Smckusick newcg->cg_magic = CG_MAGIC; 24*17937Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 25*17937Smckusick idesc.id_type = ADDR; 26*17937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 27*17937Smckusick sumsize = cgrp.cg_iused - (char *)(&cgrp); 28*17937Smckusick mapsize = howmany(MAXIPG + sblock.fs_fpg, NBBY); 29*17937Smckusick (void)time(&now); 3016267Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 3116267Smckusick if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 3216267Smckusick continue; 33*17937Smckusick if (cgrp.cg_magic != CG_MAGIC) 3416267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 35*17937Smckusick dbase = cgbase(&sblock, c); 36*17937Smckusick dmax = dbase + sblock.fs_fpg; 37*17937Smckusick if (dmax > sblock.fs_size) 38*17937Smckusick dmax = sblock.fs_size; 39*17937Smckusick if (now > cgrp.cg_time) 40*17937Smckusick newcg->cg_time = cgrp.cg_time; 41*17937Smckusick else 42*17937Smckusick newcg->cg_time = now; 43*17937Smckusick newcg->cg_cgx = c; 44*17937Smckusick if (c == sblock.fs_ncg - 1) 45*17937Smckusick newcg->cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 46*17937Smckusick else 47*17937Smckusick newcg->cg_ncyl = sblock.fs_cpg; 48*17937Smckusick newcg->cg_niblk = sblock.fs_ipg; 49*17937Smckusick newcg->cg_ndblk = dmax - dbase; 50*17937Smckusick newcg->cg_cs.cs_ndir = 0; 51*17937Smckusick newcg->cg_cs.cs_nffree = 0; 52*17937Smckusick newcg->cg_cs.cs_nbfree = 0; 53*17937Smckusick newcg->cg_cs.cs_nifree = sblock.fs_ipg; 54*17937Smckusick if (cgrp.cg_rotor < newcg->cg_ndblk) 55*17937Smckusick newcg->cg_rotor = cgrp.cg_rotor; 56*17937Smckusick else 57*17937Smckusick newcg->cg_rotor = 0; 58*17937Smckusick if (cgrp.cg_frotor < newcg->cg_ndblk) 59*17937Smckusick newcg->cg_frotor = cgrp.cg_frotor; 60*17937Smckusick else 61*17937Smckusick newcg->cg_frotor = 0; 62*17937Smckusick if (cgrp.cg_irotor < newcg->cg_niblk) 63*17937Smckusick newcg->cg_irotor = cgrp.cg_irotor; 64*17937Smckusick else 65*17937Smckusick newcg->cg_irotor = 0; 66*17937Smckusick bzero((char *)newcg->cg_frsum, sizeof newcg->cg_frsum); 67*17937Smckusick bzero((char *)newcg->cg_btot, sizeof newcg->cg_btot); 68*17937Smckusick bzero((char *)newcg->cg_b, sizeof newcg->cg_b); 69*17937Smckusick bzero((char *)newcg->cg_free, howmany(sblock.fs_fpg, NBBY)); 70*17937Smckusick bzero((char *)newcg->cg_iused, howmany(sblock.fs_ipg, NBBY)); 71*17937Smckusick j = sblock.fs_ipg * c; 72*17937Smckusick for (i = 0; i < sblock.fs_ipg; j++, i++) { 73*17937Smckusick switch (statemap[j]) { 74*17937Smckusick 75*17937Smckusick case USTATE: 76*17937Smckusick break; 77*17937Smckusick 78*17937Smckusick case DSTATE: 79*17937Smckusick case DCLEAR: 80*17937Smckusick case DFOUND: 81*17937Smckusick newcg->cg_cs.cs_ndir++; 82*17937Smckusick /* fall through */ 83*17937Smckusick 84*17937Smckusick case FSTATE: 85*17937Smckusick case FCLEAR: 86*17937Smckusick newcg->cg_cs.cs_nifree--; 87*17937Smckusick setbit(newcg->cg_iused, i); 88*17937Smckusick break; 89*17937Smckusick } 9016267Smckusick } 91*17937Smckusick if (c == 0) 92*17937Smckusick for (i = 0; i < ROOTINO; i++) { 93*17937Smckusick setbit(newcg->cg_iused, i); 94*17937Smckusick newcg->cg_cs.cs_nifree--; 9516267Smckusick } 96*17937Smckusick for (i = 0, d = dbase; 97*17937Smckusick d <= dmax - sblock.fs_frag; 98*17937Smckusick d += sblock.fs_frag, i += sblock.fs_frag) { 99*17937Smckusick frags = 0; 100*17937Smckusick for (j = 0; j < sblock.fs_frag; j++) { 101*17937Smckusick if (getbmap(d + j)) 102*17937Smckusick continue; 103*17937Smckusick setbit(newcg->cg_free, i + j); 104*17937Smckusick frags++; 105*17937Smckusick } 106*17937Smckusick if (frags == sblock.fs_frag) { 107*17937Smckusick newcg->cg_cs.cs_nbfree++; 108*17937Smckusick j = cbtocylno(&sblock, i); 109*17937Smckusick newcg->cg_btot[j]++; 110*17937Smckusick newcg->cg_b[j][cbtorpos(&sblock, i)]++; 111*17937Smckusick } else if (frags > 0) { 112*17937Smckusick newcg->cg_cs.cs_nffree += frags; 113*17937Smckusick blk = blkmap(&sblock, newcg->cg_free, i); 114*17937Smckusick fragacct(&sblock, blk, newcg->cg_frsum, 1); 115*17937Smckusick } 11616267Smckusick } 117*17937Smckusick for (frags = d; d < dmax; d++) { 118*17937Smckusick if (getbmap(d)) 119*17937Smckusick continue; 120*17937Smckusick setbit(newcg->cg_free, d - dbase); 121*17937Smckusick newcg->cg_cs.cs_nffree++; 12216267Smckusick } 123*17937Smckusick if (frags != d) { 124*17937Smckusick blk = blkmap(&sblock, newcg->cg_free, (frags - dbase)); 125*17937Smckusick fragacct(&sblock, blk, newcg->cg_frsum, 1); 12616267Smckusick } 127*17937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 128*17937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 129*17937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 130*17937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 131*17937Smckusick if (bcmp(newcg->cg_iused, cgrp.cg_iused, mapsize) != 0 && 132*17937Smckusick dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { 133*17937Smckusick bcopy(newcg->cg_iused, cgrp.cg_iused, mapsize); 134*17937Smckusick cgdirty(); 13516267Smckusick } 136*17937Smckusick if (bcmp((char *)newcg, (char *)&cgrp, sumsize) != 0 && 137*17937Smckusick dofix(&idesc, "SUMMARY INFORMATION BAD")) { 138*17937Smckusick bcopy((char *)newcg, (char *)&cgrp, sumsize); 139*17937Smckusick cgdirty(); 14016267Smckusick } 141*17937Smckusick cs = &sblock.fs_cs(&sblock, c); 142*17937Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 143*17937Smckusick dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 144*17937Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 145*17937Smckusick sbdirty(); 146*17937Smckusick } 14716267Smckusick } 148*17937Smckusick if (bcmp((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs) != 0 149*17937Smckusick && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 150*17937Smckusick bcopy((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs); 151*17937Smckusick sblock.fs_ronly = 0; 152*17937Smckusick sblock.fs_fmod = 0; 153*17937Smckusick sbdirty(); 15416267Smckusick } 15516267Smckusick } 156