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*34141Smckusick static char sccsid[] = "@(#)pass5.c 5.4 (Berkeley) 05/01/88"; 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 { 18*34141Smckusick int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 19*34141Smckusick daddr_t dbase, dmax; 20*34141Smckusick register daddr_t d; 2117937Smckusick register long i, j; 2217937Smckusick struct csum *cs; 2317937Smckusick time_t now; 2417937Smckusick struct csum cstotal; 2517937Smckusick struct inodesc idesc; 2617937Smckusick char buf[MAXBSIZE]; 2717937Smckusick register struct cg *newcg = (struct cg *)buf; 28*34141Smckusick struct ocg *ocg = (struct ocg *)buf; 2916267Smckusick 3017937Smckusick bzero((char *)newcg, sblock.fs_cgsize); 31*34141Smckusick newcg->cg_niblk = sblock.fs_ipg; 32*34141Smckusick switch (sblock.fs_postblformat) { 33*34141Smckusick 34*34141Smckusick case FS_42POSTBLFMT: 35*34141Smckusick basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 36*34141Smckusick sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 37*34141Smckusick mapsize = &ocg->cg_free[howmany(sblock.fs_fpg, NBBY)] - 38*34141Smckusick (u_char *)&ocg->cg_iused[0]; 39*34141Smckusick ocg->cg_magic = CG_MAGIC; 40*34141Smckusick savednrpos = sblock.fs_nrpos; 41*34141Smckusick sblock.fs_nrpos = 8; 42*34141Smckusick break; 43*34141Smckusick 44*34141Smckusick case FS_DYNAMICPOSTBLFMT: 45*34141Smckusick newcg->cg_btotoff = 46*34141Smckusick &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 47*34141Smckusick newcg->cg_boff = 48*34141Smckusick newcg->cg_btotoff + sblock.fs_cpg * sizeof(long); 49*34141Smckusick newcg->cg_iusedoff = newcg->cg_boff + 50*34141Smckusick sblock.fs_cpg * sblock.fs_nrpos * sizeof(short); 51*34141Smckusick newcg->cg_freeoff = 52*34141Smckusick newcg->cg_iusedoff + howmany(sblock.fs_ipg, NBBY); 53*34141Smckusick newcg->cg_nextfreeoff = newcg->cg_freeoff + 54*34141Smckusick howmany(sblock.fs_cpg * sblock.fs_spc / NSPF(&sblock), 55*34141Smckusick NBBY); 56*34141Smckusick newcg->cg_magic = CG_MAGIC; 57*34141Smckusick basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 58*34141Smckusick sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 59*34141Smckusick mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 60*34141Smckusick break; 61*34141Smckusick 62*34141Smckusick default: 63*34141Smckusick errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 64*34141Smckusick sblock.fs_postblformat); 65*34141Smckusick } 6617937Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 6717937Smckusick idesc.id_type = ADDR; 6817937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 6917937Smckusick (void)time(&now); 70*34141Smckusick for (i = sblock.fs_size; i < fragroundup(&sblock, sblock.fs_size); i++) 71*34141Smckusick setbmap(i); 7216267Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 7321540Smckusick getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); 74*34141Smckusick if (!cg_chkmagic(&cgrp)) 7516267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 7617937Smckusick dbase = cgbase(&sblock, c); 7717937Smckusick dmax = dbase + sblock.fs_fpg; 7817937Smckusick if (dmax > sblock.fs_size) 7917937Smckusick dmax = sblock.fs_size; 8017937Smckusick if (now > cgrp.cg_time) 8117937Smckusick newcg->cg_time = cgrp.cg_time; 8217937Smckusick else 8317937Smckusick newcg->cg_time = now; 8417937Smckusick newcg->cg_cgx = c; 8517937Smckusick if (c == sblock.fs_ncg - 1) 8617937Smckusick newcg->cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 8717937Smckusick else 8817937Smckusick newcg->cg_ncyl = sblock.fs_cpg; 8917937Smckusick newcg->cg_ndblk = dmax - dbase; 9017937Smckusick newcg->cg_cs.cs_ndir = 0; 9117937Smckusick newcg->cg_cs.cs_nffree = 0; 9217937Smckusick newcg->cg_cs.cs_nbfree = 0; 9317937Smckusick newcg->cg_cs.cs_nifree = sblock.fs_ipg; 9417937Smckusick if (cgrp.cg_rotor < newcg->cg_ndblk) 9517937Smckusick newcg->cg_rotor = cgrp.cg_rotor; 9617937Smckusick else 9717937Smckusick newcg->cg_rotor = 0; 9817937Smckusick if (cgrp.cg_frotor < newcg->cg_ndblk) 9917937Smckusick newcg->cg_frotor = cgrp.cg_frotor; 10017937Smckusick else 10117937Smckusick newcg->cg_frotor = 0; 10217937Smckusick if (cgrp.cg_irotor < newcg->cg_niblk) 10317937Smckusick newcg->cg_irotor = cgrp.cg_irotor; 10417937Smckusick else 10517937Smckusick newcg->cg_irotor = 0; 106*34141Smckusick bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 107*34141Smckusick bzero((char *)&cg_blktot(newcg)[0], sumsize + mapsize); 108*34141Smckusick if (sblock.fs_postblformat == FS_42POSTBLFMT) 109*34141Smckusick ocg->cg_magic = CG_MAGIC; 11017937Smckusick j = sblock.fs_ipg * c; 11117937Smckusick for (i = 0; i < sblock.fs_ipg; j++, i++) { 11217937Smckusick switch (statemap[j]) { 11317937Smckusick 11417937Smckusick case USTATE: 11517937Smckusick break; 11617937Smckusick 11717937Smckusick case DSTATE: 11817937Smckusick case DCLEAR: 11917937Smckusick case DFOUND: 12017937Smckusick newcg->cg_cs.cs_ndir++; 12117937Smckusick /* fall through */ 12217937Smckusick 12317937Smckusick case FSTATE: 12417937Smckusick case FCLEAR: 12517937Smckusick newcg->cg_cs.cs_nifree--; 126*34141Smckusick setbit(cg_inosused(newcg), i); 12717937Smckusick break; 12826480Smckusick 12926480Smckusick default: 13026480Smckusick if (j < ROOTINO) 13126480Smckusick break; 13226480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 13326480Smckusick statemap[j], j); 13417937Smckusick } 13516267Smckusick } 13617937Smckusick if (c == 0) 13717937Smckusick for (i = 0; i < ROOTINO; i++) { 138*34141Smckusick setbit(cg_inosused(newcg), i); 13917937Smckusick newcg->cg_cs.cs_nifree--; 14016267Smckusick } 14117937Smckusick for (i = 0, d = dbase; 142*34141Smckusick d < dmax; 14317937Smckusick d += sblock.fs_frag, i += sblock.fs_frag) { 14417937Smckusick frags = 0; 14517937Smckusick for (j = 0; j < sblock.fs_frag; j++) { 14617937Smckusick if (getbmap(d + j)) 14717937Smckusick continue; 148*34141Smckusick setbit(cg_blksfree(newcg), i + j); 14917937Smckusick frags++; 15017937Smckusick } 15117937Smckusick if (frags == sblock.fs_frag) { 15217937Smckusick newcg->cg_cs.cs_nbfree++; 15317937Smckusick j = cbtocylno(&sblock, i); 154*34141Smckusick cg_blktot(newcg)[j]++; 155*34141Smckusick cg_blks(&sblock, newcg, j) 156*34141Smckusick [cbtorpos(&sblock, i)]++; 15717937Smckusick } else if (frags > 0) { 15817937Smckusick newcg->cg_cs.cs_nffree += frags; 159*34141Smckusick blk = blkmap(&sblock, cg_blksfree(newcg), i); 16017937Smckusick fragacct(&sblock, blk, newcg->cg_frsum, 1); 16117937Smckusick } 16216267Smckusick } 16317937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 16417937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 16517937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 16617937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 167*34141Smckusick cs = &sblock.fs_cs(&sblock, c); 168*34141Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 169*34141Smckusick dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 170*34141Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 171*34141Smckusick sbdirty(); 172*34141Smckusick } 173*34141Smckusick if (cvtflag) { 174*34141Smckusick bcopy((char *)newcg, (char *)&cgrp, sblock.fs_cgsize); 175*34141Smckusick cgdirty(); 176*34141Smckusick continue; 177*34141Smckusick } 178*34141Smckusick if (bcmp(cg_inosused(newcg), 179*34141Smckusick cg_inosused(&cgrp), mapsize) != 0 && 18017937Smckusick dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { 181*34141Smckusick bcopy(cg_inosused(newcg), cg_inosused(&cgrp), mapsize); 18217937Smckusick cgdirty(); 18316267Smckusick } 184*34141Smckusick if ((bcmp((char *)newcg, (char *)&cgrp, basesize) != 0 || 185*34141Smckusick bcmp((char *)&cg_blktot(newcg)[0], 186*34141Smckusick (char *)&cg_blktot(&cgrp)[0], sumsize) != 0) && 18717937Smckusick dofix(&idesc, "SUMMARY INFORMATION BAD")) { 188*34141Smckusick bcopy((char *)newcg, (char *)&cgrp, basesize); 189*34141Smckusick bcopy((char *)&cg_blktot(newcg)[0], 190*34141Smckusick (char *)&cg_blktot(&cgrp)[0], sumsize); 19117937Smckusick cgdirty(); 19216267Smckusick } 19316267Smckusick } 194*34141Smckusick if (sblock.fs_postblformat == FS_42POSTBLFMT) 195*34141Smckusick sblock.fs_nrpos = savednrpos; 19617937Smckusick if (bcmp((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs) != 0 19717937Smckusick && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 19817937Smckusick bcopy((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs); 19917937Smckusick sblock.fs_ronly = 0; 20017937Smckusick sblock.fs_fmod = 0; 20117937Smckusick sbdirty(); 20216267Smckusick } 20316267Smckusick } 204