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*34223Smckusick static char sccsid[] = "@(#)pass5.c 5.5 (Berkeley) 05/07/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 { 1834141Smckusick int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 19*34223Smckusick register struct fs *fs = &sblock; 20*34223Smckusick register struct cg *cg = &cgrp; 2134141Smckusick daddr_t dbase, dmax; 2234141Smckusick register daddr_t d; 2317937Smckusick register long i, j; 2417937Smckusick struct csum *cs; 2517937Smckusick time_t now; 2617937Smckusick struct csum cstotal; 2717937Smckusick struct inodesc idesc; 2817937Smckusick char buf[MAXBSIZE]; 2917937Smckusick register struct cg *newcg = (struct cg *)buf; 3034141Smckusick struct ocg *ocg = (struct ocg *)buf; 3116267Smckusick 32*34223Smckusick bzero((char *)newcg, fs->fs_cgsize); 33*34223Smckusick newcg->cg_niblk = fs->fs_ipg; 34*34223Smckusick switch (fs->fs_postblformat) { 3534141Smckusick 3634141Smckusick case FS_42POSTBLFMT: 3734141Smckusick basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 3834141Smckusick sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 39*34223Smckusick mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 4034141Smckusick (u_char *)&ocg->cg_iused[0]; 4134141Smckusick ocg->cg_magic = CG_MAGIC; 42*34223Smckusick savednrpos = fs->fs_nrpos; 43*34223Smckusick fs->fs_nrpos = 8; 4434141Smckusick break; 4534141Smckusick 4634141Smckusick case FS_DYNAMICPOSTBLFMT: 4734141Smckusick newcg->cg_btotoff = 4834141Smckusick &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 4934141Smckusick newcg->cg_boff = 50*34223Smckusick newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 5134141Smckusick newcg->cg_iusedoff = newcg->cg_boff + 52*34223Smckusick fs->fs_cpg * fs->fs_nrpos * sizeof(short); 5334141Smckusick newcg->cg_freeoff = 54*34223Smckusick newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 5534141Smckusick newcg->cg_nextfreeoff = newcg->cg_freeoff + 56*34223Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), 5734141Smckusick NBBY); 5834141Smckusick newcg->cg_magic = CG_MAGIC; 5934141Smckusick basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 6034141Smckusick sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 6134141Smckusick mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 6234141Smckusick break; 6334141Smckusick 6434141Smckusick default: 6534141Smckusick errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 66*34223Smckusick fs->fs_postblformat); 6734141Smckusick } 6817937Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 6917937Smckusick idesc.id_type = ADDR; 7017937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 7117937Smckusick (void)time(&now); 72*34223Smckusick for (i = fs->fs_size; i < fragroundup(fs, fs->fs_size); i++) 7334141Smckusick setbmap(i); 74*34223Smckusick for (c = 0; c < fs->fs_ncg; c++) { 75*34223Smckusick getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 76*34223Smckusick if (!cg_chkmagic(cg)) 7716267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 78*34223Smckusick dbase = cgbase(fs, c); 79*34223Smckusick dmax = dbase + fs->fs_fpg; 80*34223Smckusick if (dmax > fs->fs_size) 81*34223Smckusick dmax = fs->fs_size; 82*34223Smckusick if (now > cg->cg_time) 83*34223Smckusick newcg->cg_time = cg->cg_time; 8417937Smckusick else 8517937Smckusick newcg->cg_time = now; 8617937Smckusick newcg->cg_cgx = c; 87*34223Smckusick if (c == fs->fs_ncg - 1) 88*34223Smckusick newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 8917937Smckusick else 90*34223Smckusick newcg->cg_ncyl = fs->fs_cpg; 9117937Smckusick newcg->cg_ndblk = dmax - dbase; 9217937Smckusick newcg->cg_cs.cs_ndir = 0; 9317937Smckusick newcg->cg_cs.cs_nffree = 0; 9417937Smckusick newcg->cg_cs.cs_nbfree = 0; 95*34223Smckusick newcg->cg_cs.cs_nifree = fs->fs_ipg; 96*34223Smckusick if (cg->cg_rotor < newcg->cg_ndblk) 97*34223Smckusick newcg->cg_rotor = cg->cg_rotor; 9817937Smckusick else 9917937Smckusick newcg->cg_rotor = 0; 100*34223Smckusick if (cg->cg_frotor < newcg->cg_ndblk) 101*34223Smckusick newcg->cg_frotor = cg->cg_frotor; 10217937Smckusick else 10317937Smckusick newcg->cg_frotor = 0; 104*34223Smckusick if (cg->cg_irotor < newcg->cg_niblk) 105*34223Smckusick newcg->cg_irotor = cg->cg_irotor; 10617937Smckusick else 10717937Smckusick newcg->cg_irotor = 0; 10834141Smckusick bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 10934141Smckusick bzero((char *)&cg_blktot(newcg)[0], sumsize + mapsize); 110*34223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 11134141Smckusick ocg->cg_magic = CG_MAGIC; 112*34223Smckusick j = fs->fs_ipg * c; 113*34223Smckusick for (i = 0; i < fs->fs_ipg; j++, i++) { 11417937Smckusick switch (statemap[j]) { 11517937Smckusick 11617937Smckusick case USTATE: 11717937Smckusick break; 11817937Smckusick 11917937Smckusick case DSTATE: 12017937Smckusick case DCLEAR: 12117937Smckusick case DFOUND: 12217937Smckusick newcg->cg_cs.cs_ndir++; 12317937Smckusick /* fall through */ 12417937Smckusick 12517937Smckusick case FSTATE: 12617937Smckusick case FCLEAR: 12717937Smckusick newcg->cg_cs.cs_nifree--; 12834141Smckusick setbit(cg_inosused(newcg), i); 12917937Smckusick break; 13026480Smckusick 13126480Smckusick default: 13226480Smckusick if (j < ROOTINO) 13326480Smckusick break; 13426480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 13526480Smckusick statemap[j], j); 13617937Smckusick } 13716267Smckusick } 13817937Smckusick if (c == 0) 13917937Smckusick for (i = 0; i < ROOTINO; i++) { 14034141Smckusick setbit(cg_inosused(newcg), i); 14117937Smckusick newcg->cg_cs.cs_nifree--; 14216267Smckusick } 14317937Smckusick for (i = 0, d = dbase; 14434141Smckusick d < dmax; 145*34223Smckusick d += fs->fs_frag, i += fs->fs_frag) { 14617937Smckusick frags = 0; 147*34223Smckusick for (j = 0; j < fs->fs_frag; j++) { 14817937Smckusick if (getbmap(d + j)) 14917937Smckusick continue; 15034141Smckusick setbit(cg_blksfree(newcg), i + j); 15117937Smckusick frags++; 15217937Smckusick } 153*34223Smckusick if (frags == fs->fs_frag) { 15417937Smckusick newcg->cg_cs.cs_nbfree++; 155*34223Smckusick j = cbtocylno(fs, i); 15634141Smckusick cg_blktot(newcg)[j]++; 157*34223Smckusick cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 15817937Smckusick } else if (frags > 0) { 15917937Smckusick newcg->cg_cs.cs_nffree += frags; 160*34223Smckusick blk = blkmap(fs, cg_blksfree(newcg), i); 161*34223Smckusick fragacct(fs, blk, newcg->cg_frsum, 1); 16217937Smckusick } 16316267Smckusick } 16417937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 16517937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 16617937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 16717937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 168*34223Smckusick cs = &fs->fs_cs(fs, c); 16934141Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 17034141Smckusick dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 17134141Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 17234141Smckusick sbdirty(); 17334141Smckusick } 17434141Smckusick if (cvtflag) { 175*34223Smckusick bcopy((char *)newcg, (char *)cg, fs->fs_cgsize); 17634141Smckusick cgdirty(); 17734141Smckusick continue; 17834141Smckusick } 17934141Smckusick if (bcmp(cg_inosused(newcg), 180*34223Smckusick cg_inosused(cg), mapsize) != 0 && 18117937Smckusick dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { 182*34223Smckusick bcopy(cg_inosused(newcg), cg_inosused(cg), mapsize); 18317937Smckusick cgdirty(); 18416267Smckusick } 185*34223Smckusick if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 18634141Smckusick bcmp((char *)&cg_blktot(newcg)[0], 187*34223Smckusick (char *)&cg_blktot(cg)[0], sumsize) != 0) && 18817937Smckusick dofix(&idesc, "SUMMARY INFORMATION BAD")) { 189*34223Smckusick bcopy((char *)newcg, (char *)cg, basesize); 19034141Smckusick bcopy((char *)&cg_blktot(newcg)[0], 191*34223Smckusick (char *)&cg_blktot(cg)[0], sumsize); 19217937Smckusick cgdirty(); 19316267Smckusick } 19416267Smckusick } 195*34223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 196*34223Smckusick fs->fs_nrpos = savednrpos; 197*34223Smckusick if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 19817937Smckusick && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 199*34223Smckusick bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 200*34223Smckusick fs->fs_ronly = 0; 201*34223Smckusick fs->fs_fmod = 0; 20217937Smckusick sbdirty(); 20316267Smckusick } 20416267Smckusick } 205