122053Sdist /* 239976Smckusick * Copyright (c) 1980, 1986 The Regents of the University of California. 339976Smckusick * All rights reserved. 439976Smckusick * 542702Sbostic * %sccs.include.redist.c% 622053Sdist */ 722053Sdist 816267Smckusick #ifndef lint 9*54601Smckusick static char sccsid[] = "@(#)pass5.c 5.17 (Berkeley) 07/02/92"; 1039976Smckusick #endif /* not lint */ 1116267Smckusick 1216267Smckusick #include <sys/param.h> 1353703Smckusick #include <sys/time.h> 1451532Sbostic #include <ufs/ufs/dinode.h> 1551532Sbostic #include <ufs/ffs/fs.h> 1644934Smckusick #include <string.h> 1716267Smckusick #include "fsck.h" 1816267Smckusick 1916267Smckusick pass5() 2016267Smckusick { 2134141Smckusick int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 2234223Smckusick register struct fs *fs = &sblock; 2334223Smckusick register struct cg *cg = &cgrp; 2434141Smckusick daddr_t dbase, dmax; 2534141Smckusick register daddr_t d; 2617937Smckusick register long i, j; 2717937Smckusick struct csum *cs; 2817937Smckusick time_t now; 2917937Smckusick struct csum cstotal; 3037099Smckusick struct inodesc idesc[3]; 3117937Smckusick char buf[MAXBSIZE]; 3217937Smckusick register struct cg *newcg = (struct cg *)buf; 3334141Smckusick struct ocg *ocg = (struct ocg *)buf; 3416267Smckusick 3544934Smckusick bzero((char *)newcg, (size_t)fs->fs_cgsize); 3634223Smckusick newcg->cg_niblk = fs->fs_ipg; 3739973Smckusick switch ((int)fs->fs_postblformat) { 3834141Smckusick 3934141Smckusick case FS_42POSTBLFMT: 4034141Smckusick basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 4134141Smckusick sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 4234223Smckusick mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 4334141Smckusick (u_char *)&ocg->cg_iused[0]; 4434141Smckusick ocg->cg_magic = CG_MAGIC; 4534223Smckusick savednrpos = fs->fs_nrpos; 4634223Smckusick fs->fs_nrpos = 8; 4734141Smckusick break; 4834141Smckusick 4934141Smckusick case FS_DYNAMICPOSTBLFMT: 5034141Smckusick newcg->cg_btotoff = 5134141Smckusick &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 5234141Smckusick newcg->cg_boff = 5334223Smckusick newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 5434141Smckusick newcg->cg_iusedoff = newcg->cg_boff + 5534223Smckusick fs->fs_cpg * fs->fs_nrpos * sizeof(short); 5634141Smckusick newcg->cg_freeoff = 5734223Smckusick newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 5834141Smckusick newcg->cg_nextfreeoff = newcg->cg_freeoff + 5934223Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), 6034141Smckusick NBBY); 6134141Smckusick newcg->cg_magic = CG_MAGIC; 6234141Smckusick basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 6334141Smckusick sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 6434141Smckusick mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 6534141Smckusick break; 6634141Smckusick 6734141Smckusick default: 6834141Smckusick errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 6934223Smckusick fs->fs_postblformat); 7034141Smckusick } 7137099Smckusick bzero((char *)&idesc[0], sizeof idesc); 72*54601Smckusick for (i = 0; i < 3; i++) { 7337099Smckusick idesc[i].id_type = ADDR; 74*54601Smckusick if (doinglevel2) 75*54601Smckusick idesc[i].id_fix = FIX; 76*54601Smckusick } 7717937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 7817937Smckusick (void)time(&now); 7940018Smckusick j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 8040018Smckusick for (i = fs->fs_size; i < j; i++) 8134141Smckusick setbmap(i); 8234223Smckusick for (c = 0; c < fs->fs_ncg; c++) { 8334223Smckusick getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 8434223Smckusick if (!cg_chkmagic(cg)) 8516267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 8634223Smckusick dbase = cgbase(fs, c); 8734223Smckusick dmax = dbase + fs->fs_fpg; 8834223Smckusick if (dmax > fs->fs_size) 8934223Smckusick dmax = fs->fs_size; 9034223Smckusick if (now > cg->cg_time) 9134223Smckusick newcg->cg_time = cg->cg_time; 9217937Smckusick else 9317937Smckusick newcg->cg_time = now; 9417937Smckusick newcg->cg_cgx = c; 9534223Smckusick if (c == fs->fs_ncg - 1) 9634223Smckusick newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 9717937Smckusick else 9834223Smckusick newcg->cg_ncyl = fs->fs_cpg; 9917937Smckusick newcg->cg_ndblk = dmax - dbase; 10017937Smckusick newcg->cg_cs.cs_ndir = 0; 10117937Smckusick newcg->cg_cs.cs_nffree = 0; 10217937Smckusick newcg->cg_cs.cs_nbfree = 0; 10334223Smckusick newcg->cg_cs.cs_nifree = fs->fs_ipg; 10434223Smckusick if (cg->cg_rotor < newcg->cg_ndblk) 10534223Smckusick newcg->cg_rotor = cg->cg_rotor; 10617937Smckusick else 10717937Smckusick newcg->cg_rotor = 0; 10834223Smckusick if (cg->cg_frotor < newcg->cg_ndblk) 10934223Smckusick newcg->cg_frotor = cg->cg_frotor; 11017937Smckusick else 11117937Smckusick newcg->cg_frotor = 0; 11234223Smckusick if (cg->cg_irotor < newcg->cg_niblk) 11334223Smckusick newcg->cg_irotor = cg->cg_irotor; 11417937Smckusick else 11517937Smckusick newcg->cg_irotor = 0; 11634141Smckusick bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 11744934Smckusick bzero((char *)&cg_blktot(newcg)[0], 11844934Smckusick (size_t)(sumsize + mapsize)); 11934223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 12034141Smckusick ocg->cg_magic = CG_MAGIC; 12134223Smckusick j = fs->fs_ipg * c; 12234223Smckusick for (i = 0; i < fs->fs_ipg; j++, i++) { 12317937Smckusick switch (statemap[j]) { 12417937Smckusick 12517937Smckusick case USTATE: 12617937Smckusick break; 12717937Smckusick 12817937Smckusick case DSTATE: 12917937Smckusick case DCLEAR: 13017937Smckusick case DFOUND: 13117937Smckusick newcg->cg_cs.cs_ndir++; 13217937Smckusick /* fall through */ 13317937Smckusick 13417937Smckusick case FSTATE: 13517937Smckusick case FCLEAR: 13617937Smckusick newcg->cg_cs.cs_nifree--; 13734141Smckusick setbit(cg_inosused(newcg), i); 13817937Smckusick break; 13926480Smckusick 14026480Smckusick default: 14126480Smckusick if (j < ROOTINO) 14226480Smckusick break; 14326480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 14426480Smckusick statemap[j], j); 14517937Smckusick } 14616267Smckusick } 14717937Smckusick if (c == 0) 14817937Smckusick for (i = 0; i < ROOTINO; i++) { 14934141Smckusick setbit(cg_inosused(newcg), i); 15017937Smckusick newcg->cg_cs.cs_nifree--; 15116267Smckusick } 15217937Smckusick for (i = 0, d = dbase; 15334141Smckusick d < dmax; 15434223Smckusick d += fs->fs_frag, i += fs->fs_frag) { 15517937Smckusick frags = 0; 15634223Smckusick for (j = 0; j < fs->fs_frag; j++) { 15739973Smckusick if (testbmap(d + j)) 15817937Smckusick continue; 15934141Smckusick setbit(cg_blksfree(newcg), i + j); 16017937Smckusick frags++; 16117937Smckusick } 16234223Smckusick if (frags == fs->fs_frag) { 16317937Smckusick newcg->cg_cs.cs_nbfree++; 16434223Smckusick j = cbtocylno(fs, i); 16534141Smckusick cg_blktot(newcg)[j]++; 16634223Smckusick cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 16717937Smckusick } else if (frags > 0) { 16817937Smckusick newcg->cg_cs.cs_nffree += frags; 16934223Smckusick blk = blkmap(fs, cg_blksfree(newcg), i); 17051637Sbostic ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 17117937Smckusick } 17216267Smckusick } 17317937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 17417937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 17517937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 17617937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 17734223Smckusick cs = &fs->fs_cs(fs, c); 17834141Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 17937099Smckusick dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 18034141Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 18134141Smckusick sbdirty(); 18234141Smckusick } 183*54601Smckusick if (doinglevel1) { 18444934Smckusick bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); 18534141Smckusick cgdirty(); 18634141Smckusick continue; 18734141Smckusick } 18834141Smckusick if (bcmp(cg_inosused(newcg), 18934223Smckusick cg_inosused(cg), mapsize) != 0 && 19037099Smckusick dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 19144934Smckusick bcopy(cg_inosused(newcg), cg_inosused(cg), 19244934Smckusick (size_t)mapsize); 19317937Smckusick cgdirty(); 19416267Smckusick } 19534223Smckusick if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 19634141Smckusick bcmp((char *)&cg_blktot(newcg)[0], 19734223Smckusick (char *)&cg_blktot(cg)[0], sumsize) != 0) && 19837099Smckusick dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 19944934Smckusick bcopy((char *)newcg, (char *)cg, (size_t)basesize); 20034141Smckusick bcopy((char *)&cg_blktot(newcg)[0], 20144934Smckusick (char *)&cg_blktot(cg)[0], (size_t)sumsize); 20217937Smckusick cgdirty(); 20316267Smckusick } 20416267Smckusick } 20534223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 20634223Smckusick fs->fs_nrpos = savednrpos; 20734223Smckusick if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 20837099Smckusick && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 20934223Smckusick bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 21034223Smckusick fs->fs_ronly = 0; 21134223Smckusick fs->fs_fmod = 0; 21217937Smckusick sbdirty(); 21316267Smckusick } 21416267Smckusick } 215