122053Sdist /* 222053Sdist * Copyright (c) 1980 Regents of the University of California. 322053Sdist * All rights reserved. The Berkeley software License Agreement 422053Sdist * specifies the terms and conditions for redistribution. 522053Sdist */ 622053Sdist 716267Smckusick #ifndef lint 8*26480Smckusick static char sccsid[] = "@(#)pass5.c 5.2 (Berkeley) 03/05/86"; 922053Sdist #endif not lint 1016267Smckusick 1116267Smckusick #include <sys/param.h> 1216267Smckusick #include <sys/inode.h> 1316267Smckusick #include <sys/fs.h> 1416267Smckusick #include "fsck.h" 1516267Smckusick 1616267Smckusick pass5() 1716267Smckusick { 1817937Smckusick int c, blk, frags, sumsize, mapsize; 1917937Smckusick daddr_t dbase, dmax, d; 2017937Smckusick register long i, j; 2117937Smckusick struct csum *cs; 2217937Smckusick time_t now; 2317937Smckusick struct csum cstotal; 2417937Smckusick struct inodesc idesc; 2517937Smckusick char buf[MAXBSIZE]; 2617937Smckusick register struct cg *newcg = (struct cg *)buf; 2716267Smckusick 2817937Smckusick bzero((char *)newcg, sblock.fs_cgsize); 2917937Smckusick newcg->cg_magic = CG_MAGIC; 3017937Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 3117937Smckusick idesc.id_type = ADDR; 3217937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 3317937Smckusick sumsize = cgrp.cg_iused - (char *)(&cgrp); 3418667Smckusick mapsize = &cgrp.cg_free[howmany(sblock.fs_fpg, NBBY)] - 3518667Smckusick (u_char *)cgrp.cg_iused; 3617937Smckusick (void)time(&now); 3716267Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 3821540Smckusick getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); 3917937Smckusick if (cgrp.cg_magic != CG_MAGIC) 4016267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 4117937Smckusick dbase = cgbase(&sblock, c); 4217937Smckusick dmax = dbase + sblock.fs_fpg; 4317937Smckusick if (dmax > sblock.fs_size) 4417937Smckusick dmax = sblock.fs_size; 4517937Smckusick if (now > cgrp.cg_time) 4617937Smckusick newcg->cg_time = cgrp.cg_time; 4717937Smckusick else 4817937Smckusick newcg->cg_time = now; 4917937Smckusick newcg->cg_cgx = c; 5017937Smckusick if (c == sblock.fs_ncg - 1) 5117937Smckusick newcg->cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 5217937Smckusick else 5317937Smckusick newcg->cg_ncyl = sblock.fs_cpg; 5417937Smckusick newcg->cg_niblk = sblock.fs_ipg; 5517937Smckusick newcg->cg_ndblk = dmax - dbase; 5617937Smckusick newcg->cg_cs.cs_ndir = 0; 5717937Smckusick newcg->cg_cs.cs_nffree = 0; 5817937Smckusick newcg->cg_cs.cs_nbfree = 0; 5917937Smckusick newcg->cg_cs.cs_nifree = sblock.fs_ipg; 6017937Smckusick if (cgrp.cg_rotor < newcg->cg_ndblk) 6117937Smckusick newcg->cg_rotor = cgrp.cg_rotor; 6217937Smckusick else 6317937Smckusick newcg->cg_rotor = 0; 6417937Smckusick if (cgrp.cg_frotor < newcg->cg_ndblk) 6517937Smckusick newcg->cg_frotor = cgrp.cg_frotor; 6617937Smckusick else 6717937Smckusick newcg->cg_frotor = 0; 6817937Smckusick if (cgrp.cg_irotor < newcg->cg_niblk) 6917937Smckusick newcg->cg_irotor = cgrp.cg_irotor; 7017937Smckusick else 7117937Smckusick newcg->cg_irotor = 0; 7217937Smckusick bzero((char *)newcg->cg_frsum, sizeof newcg->cg_frsum); 7317937Smckusick bzero((char *)newcg->cg_btot, sizeof newcg->cg_btot); 7417937Smckusick bzero((char *)newcg->cg_b, sizeof newcg->cg_b); 7517937Smckusick bzero((char *)newcg->cg_free, howmany(sblock.fs_fpg, NBBY)); 7617937Smckusick bzero((char *)newcg->cg_iused, howmany(sblock.fs_ipg, NBBY)); 7717937Smckusick j = sblock.fs_ipg * c; 7817937Smckusick for (i = 0; i < sblock.fs_ipg; j++, i++) { 7917937Smckusick switch (statemap[j]) { 8017937Smckusick 8117937Smckusick case USTATE: 8217937Smckusick break; 8317937Smckusick 8417937Smckusick case DSTATE: 8517937Smckusick case DCLEAR: 8617937Smckusick case DFOUND: 8717937Smckusick newcg->cg_cs.cs_ndir++; 8817937Smckusick /* fall through */ 8917937Smckusick 9017937Smckusick case FSTATE: 9117937Smckusick case FCLEAR: 9217937Smckusick newcg->cg_cs.cs_nifree--; 9317937Smckusick setbit(newcg->cg_iused, i); 9417937Smckusick break; 95*26480Smckusick 96*26480Smckusick default: 97*26480Smckusick if (j < ROOTINO) 98*26480Smckusick break; 99*26480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 100*26480Smckusick statemap[j], j); 10117937Smckusick } 10216267Smckusick } 10317937Smckusick if (c == 0) 10417937Smckusick for (i = 0; i < ROOTINO; i++) { 10517937Smckusick setbit(newcg->cg_iused, i); 10617937Smckusick newcg->cg_cs.cs_nifree--; 10716267Smckusick } 10817937Smckusick for (i = 0, d = dbase; 10917937Smckusick d <= dmax - sblock.fs_frag; 11017937Smckusick d += sblock.fs_frag, i += sblock.fs_frag) { 11117937Smckusick frags = 0; 11217937Smckusick for (j = 0; j < sblock.fs_frag; j++) { 11317937Smckusick if (getbmap(d + j)) 11417937Smckusick continue; 11517937Smckusick setbit(newcg->cg_free, i + j); 11617937Smckusick frags++; 11717937Smckusick } 11817937Smckusick if (frags == sblock.fs_frag) { 11917937Smckusick newcg->cg_cs.cs_nbfree++; 12017937Smckusick j = cbtocylno(&sblock, i); 12117937Smckusick newcg->cg_btot[j]++; 12217937Smckusick newcg->cg_b[j][cbtorpos(&sblock, i)]++; 12317937Smckusick } else if (frags > 0) { 12417937Smckusick newcg->cg_cs.cs_nffree += frags; 12517937Smckusick blk = blkmap(&sblock, newcg->cg_free, i); 12617937Smckusick fragacct(&sblock, blk, newcg->cg_frsum, 1); 12717937Smckusick } 12816267Smckusick } 12917937Smckusick for (frags = d; d < dmax; d++) { 13017937Smckusick if (getbmap(d)) 13117937Smckusick continue; 13217937Smckusick setbit(newcg->cg_free, d - dbase); 13317937Smckusick newcg->cg_cs.cs_nffree++; 13416267Smckusick } 13517937Smckusick if (frags != d) { 13617937Smckusick blk = blkmap(&sblock, newcg->cg_free, (frags - dbase)); 13717937Smckusick fragacct(&sblock, blk, newcg->cg_frsum, 1); 13816267Smckusick } 13917937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 14017937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 14117937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 14217937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 14317937Smckusick if (bcmp(newcg->cg_iused, cgrp.cg_iused, mapsize) != 0 && 14417937Smckusick dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { 14517937Smckusick bcopy(newcg->cg_iused, cgrp.cg_iused, mapsize); 14617937Smckusick cgdirty(); 14716267Smckusick } 14817937Smckusick if (bcmp((char *)newcg, (char *)&cgrp, sumsize) != 0 && 14917937Smckusick dofix(&idesc, "SUMMARY INFORMATION BAD")) { 15017937Smckusick bcopy((char *)newcg, (char *)&cgrp, sumsize); 15117937Smckusick cgdirty(); 15216267Smckusick } 15317937Smckusick cs = &sblock.fs_cs(&sblock, c); 15417937Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 15517937Smckusick dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 15617937Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 15717937Smckusick sbdirty(); 15817937Smckusick } 15916267Smckusick } 16017937Smckusick if (bcmp((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs) != 0 16117937Smckusick && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 16217937Smckusick bcopy((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs); 16317937Smckusick sblock.fs_ronly = 0; 16417937Smckusick sblock.fs_fmod = 0; 16517937Smckusick sbdirty(); 16616267Smckusick } 16716267Smckusick } 168