122053Sdist /* 239976Smckusick * Copyright (c) 1980, 1986 The Regents of the University of California. 339976Smckusick * All rights reserved. 439976Smckusick * 539976Smckusick * Redistribution and use in source and binary forms are permitted 639976Smckusick * provided that the above copyright notice and this paragraph are 739976Smckusick * duplicated in all such forms and that any documentation, 839976Smckusick * advertising materials, and other materials related to such 939976Smckusick * distribution and use acknowledge that the software was developed 1039976Smckusick * by the University of California, Berkeley. The name of the 1139976Smckusick * University may not be used to endorse or promote products derived 1239976Smckusick * from this software without specific prior written permission. 1339976Smckusick * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1439976Smckusick * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1539976Smckusick * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1622053Sdist */ 1722053Sdist 1816267Smckusick #ifndef lint 19*40018Smckusick static char sccsid[] = "@(#)pass5.c 5.11 (Berkeley) 02/06/90"; 2039976Smckusick #endif /* not lint */ 2116267Smckusick 2216267Smckusick #include <sys/param.h> 2339383Smckusick #include <ufs/dinode.h> 2438337Smckusick #include <ufs/fs.h> 2516267Smckusick #include "fsck.h" 2616267Smckusick 2716267Smckusick pass5() 2816267Smckusick { 2934141Smckusick int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 3034223Smckusick register struct fs *fs = &sblock; 3134223Smckusick register struct cg *cg = &cgrp; 3234141Smckusick daddr_t dbase, dmax; 3334141Smckusick register daddr_t d; 3417937Smckusick register long i, j; 3517937Smckusick struct csum *cs; 3617937Smckusick time_t now; 3717937Smckusick struct csum cstotal; 3837099Smckusick struct inodesc idesc[3]; 3917937Smckusick char buf[MAXBSIZE]; 4017937Smckusick register struct cg *newcg = (struct cg *)buf; 4134141Smckusick struct ocg *ocg = (struct ocg *)buf; 4216267Smckusick 4339973Smckusick bzero((char *)newcg, (int)fs->fs_cgsize); 4434223Smckusick newcg->cg_niblk = fs->fs_ipg; 4539973Smckusick switch ((int)fs->fs_postblformat) { 4634141Smckusick 4734141Smckusick case FS_42POSTBLFMT: 4834141Smckusick basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 4934141Smckusick sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 5034223Smckusick mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 5134141Smckusick (u_char *)&ocg->cg_iused[0]; 5234141Smckusick ocg->cg_magic = CG_MAGIC; 5334223Smckusick savednrpos = fs->fs_nrpos; 5434223Smckusick fs->fs_nrpos = 8; 5534141Smckusick break; 5634141Smckusick 5734141Smckusick case FS_DYNAMICPOSTBLFMT: 5834141Smckusick newcg->cg_btotoff = 5934141Smckusick &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 6034141Smckusick newcg->cg_boff = 6134223Smckusick newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 6234141Smckusick newcg->cg_iusedoff = newcg->cg_boff + 6334223Smckusick fs->fs_cpg * fs->fs_nrpos * sizeof(short); 6434141Smckusick newcg->cg_freeoff = 6534223Smckusick newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 6634141Smckusick newcg->cg_nextfreeoff = newcg->cg_freeoff + 6734223Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), 6834141Smckusick NBBY); 6934141Smckusick newcg->cg_magic = CG_MAGIC; 7034141Smckusick basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 7134141Smckusick sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 7234141Smckusick mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 7334141Smckusick break; 7434141Smckusick 7534141Smckusick default: 7634141Smckusick errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 7734223Smckusick fs->fs_postblformat); 7834141Smckusick } 7937099Smckusick bzero((char *)&idesc[0], sizeof idesc); 8037099Smckusick for (i = 0; i < 3; i++) 8137099Smckusick idesc[i].id_type = ADDR; 8217937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 8317937Smckusick (void)time(&now); 84*40018Smckusick j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 85*40018Smckusick for (i = fs->fs_size; i < j; i++) 8634141Smckusick setbmap(i); 8734223Smckusick for (c = 0; c < fs->fs_ncg; c++) { 8834223Smckusick getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 8934223Smckusick if (!cg_chkmagic(cg)) 9016267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 9134223Smckusick dbase = cgbase(fs, c); 9234223Smckusick dmax = dbase + fs->fs_fpg; 9334223Smckusick if (dmax > fs->fs_size) 9434223Smckusick dmax = fs->fs_size; 9534223Smckusick if (now > cg->cg_time) 9634223Smckusick newcg->cg_time = cg->cg_time; 9717937Smckusick else 9817937Smckusick newcg->cg_time = now; 9917937Smckusick newcg->cg_cgx = c; 10034223Smckusick if (c == fs->fs_ncg - 1) 10134223Smckusick newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 10217937Smckusick else 10334223Smckusick newcg->cg_ncyl = fs->fs_cpg; 10417937Smckusick newcg->cg_ndblk = dmax - dbase; 10517937Smckusick newcg->cg_cs.cs_ndir = 0; 10617937Smckusick newcg->cg_cs.cs_nffree = 0; 10717937Smckusick newcg->cg_cs.cs_nbfree = 0; 10834223Smckusick newcg->cg_cs.cs_nifree = fs->fs_ipg; 10934223Smckusick if (cg->cg_rotor < newcg->cg_ndblk) 11034223Smckusick newcg->cg_rotor = cg->cg_rotor; 11117937Smckusick else 11217937Smckusick newcg->cg_rotor = 0; 11334223Smckusick if (cg->cg_frotor < newcg->cg_ndblk) 11434223Smckusick newcg->cg_frotor = cg->cg_frotor; 11517937Smckusick else 11617937Smckusick newcg->cg_frotor = 0; 11734223Smckusick if (cg->cg_irotor < newcg->cg_niblk) 11834223Smckusick newcg->cg_irotor = cg->cg_irotor; 11917937Smckusick else 12017937Smckusick newcg->cg_irotor = 0; 12134141Smckusick bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 12234141Smckusick bzero((char *)&cg_blktot(newcg)[0], sumsize + mapsize); 12334223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 12434141Smckusick ocg->cg_magic = CG_MAGIC; 12534223Smckusick j = fs->fs_ipg * c; 12634223Smckusick for (i = 0; i < fs->fs_ipg; j++, i++) { 12717937Smckusick switch (statemap[j]) { 12817937Smckusick 12917937Smckusick case USTATE: 13017937Smckusick break; 13117937Smckusick 13217937Smckusick case DSTATE: 13317937Smckusick case DCLEAR: 13417937Smckusick case DFOUND: 13517937Smckusick newcg->cg_cs.cs_ndir++; 13617937Smckusick /* fall through */ 13717937Smckusick 13817937Smckusick case FSTATE: 13917937Smckusick case FCLEAR: 14017937Smckusick newcg->cg_cs.cs_nifree--; 14134141Smckusick setbit(cg_inosused(newcg), i); 14217937Smckusick break; 14326480Smckusick 14426480Smckusick default: 14526480Smckusick if (j < ROOTINO) 14626480Smckusick break; 14726480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 14826480Smckusick statemap[j], j); 14917937Smckusick } 15016267Smckusick } 15117937Smckusick if (c == 0) 15217937Smckusick for (i = 0; i < ROOTINO; i++) { 15334141Smckusick setbit(cg_inosused(newcg), i); 15417937Smckusick newcg->cg_cs.cs_nifree--; 15516267Smckusick } 15617937Smckusick for (i = 0, d = dbase; 15734141Smckusick d < dmax; 15834223Smckusick d += fs->fs_frag, i += fs->fs_frag) { 15917937Smckusick frags = 0; 16034223Smckusick for (j = 0; j < fs->fs_frag; j++) { 16139973Smckusick if (testbmap(d + j)) 16217937Smckusick continue; 16334141Smckusick setbit(cg_blksfree(newcg), i + j); 16417937Smckusick frags++; 16517937Smckusick } 16634223Smckusick if (frags == fs->fs_frag) { 16717937Smckusick newcg->cg_cs.cs_nbfree++; 16834223Smckusick j = cbtocylno(fs, i); 16934141Smckusick cg_blktot(newcg)[j]++; 17034223Smckusick cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 17117937Smckusick } else if (frags > 0) { 17217937Smckusick newcg->cg_cs.cs_nffree += frags; 17334223Smckusick blk = blkmap(fs, cg_blksfree(newcg), i); 17434223Smckusick fragacct(fs, blk, newcg->cg_frsum, 1); 17517937Smckusick } 17616267Smckusick } 17717937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 17817937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 17917937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 18017937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 18134223Smckusick cs = &fs->fs_cs(fs, c); 18234141Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 18337099Smckusick dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 18434141Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 18534141Smckusick sbdirty(); 18634141Smckusick } 18734141Smckusick if (cvtflag) { 18839973Smckusick bcopy((char *)newcg, (char *)cg, (int)fs->fs_cgsize); 18934141Smckusick cgdirty(); 19034141Smckusick continue; 19134141Smckusick } 19234141Smckusick if (bcmp(cg_inosused(newcg), 19334223Smckusick cg_inosused(cg), mapsize) != 0 && 19437099Smckusick dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 19534223Smckusick bcopy(cg_inosused(newcg), cg_inosused(cg), mapsize); 19617937Smckusick cgdirty(); 19716267Smckusick } 19834223Smckusick if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 19934141Smckusick bcmp((char *)&cg_blktot(newcg)[0], 20034223Smckusick (char *)&cg_blktot(cg)[0], sumsize) != 0) && 20137099Smckusick dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 20234223Smckusick bcopy((char *)newcg, (char *)cg, basesize); 20334141Smckusick bcopy((char *)&cg_blktot(newcg)[0], 20434223Smckusick (char *)&cg_blktot(cg)[0], sumsize); 20517937Smckusick cgdirty(); 20616267Smckusick } 20716267Smckusick } 20834223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 20934223Smckusick fs->fs_nrpos = savednrpos; 21034223Smckusick if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 21137099Smckusick && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 21234223Smckusick bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 21334223Smckusick fs->fs_ronly = 0; 21434223Smckusick fs->fs_fmod = 0; 21517937Smckusick sbdirty(); 21616267Smckusick } 21716267Smckusick } 218