122053Sdist /* 261492Sbostic * Copyright (c) 1980, 1986, 1993 361492Sbostic * The Regents of the University of California. All rights reserved. 439976Smckusick * 542702Sbostic * %sccs.include.redist.c% 622053Sdist */ 722053Sdist 816267Smckusick #ifndef lint 9*68548Smckusick static char sccsid[] = "@(#)pass5.c 8.7 (Berkeley) 03/21/95"; 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; 22*68548Smckusick struct fs *fs = &sblock; 23*68548Smckusick struct cg *cg = &cgrp; 24*68548Smckusick ufs_daddr_t dbase, dmax; 25*68548Smckusick ufs_daddr_t d; 26*68548Smckusick long i, j; 2717937Smckusick struct csum *cs; 2817937Smckusick struct csum cstotal; 2937099Smckusick struct inodesc idesc[3]; 3017937Smckusick char buf[MAXBSIZE]; 3117937Smckusick register struct cg *newcg = (struct cg *)buf; 3234141Smckusick struct ocg *ocg = (struct ocg *)buf; 3316267Smckusick 3467879Smckusick statemap[WINO] = USTATE; 3544934Smckusick bzero((char *)newcg, (size_t)fs->fs_cgsize); 3634223Smckusick newcg->cg_niblk = fs->fs_ipg; 3768007Smckusick if (cvtlevel >= 3) { 3865969Smckusick if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { 3965969Smckusick if (preen) 4065969Smckusick pwarn("DELETING CLUSTERING MAPS\n"); 4165969Smckusick if (preen || reply("DELETE CLUSTERING MAPS")) { 4265969Smckusick fs->fs_contigsumsize = 0; 4365969Smckusick doinglevel1 = 1; 4465969Smckusick sbdirty(); 4565969Smckusick } 4665969Smckusick } 4765969Smckusick if (fs->fs_maxcontig > 1) { 4865969Smckusick char *doit = 0; 4965969Smckusick 5065969Smckusick if (fs->fs_contigsumsize < 1) { 5165969Smckusick doit = "CREAT"; 5265969Smckusick } else if (fs->fs_contigsumsize < fs->fs_maxcontig && 5365969Smckusick fs->fs_contigsumsize < FS_MAXCONTIG) { 5465969Smckusick doit = "EXPAND"; 5565969Smckusick } 5665969Smckusick if (doit) { 5765969Smckusick i = fs->fs_contigsumsize; 5865969Smckusick fs->fs_contigsumsize = 5965969Smckusick MIN(fs->fs_maxcontig, FS_MAXCONTIG); 6065969Smckusick if (CGSIZE(fs) > fs->fs_bsize) { 6165969Smckusick pwarn("CANNOT %s CLUSTER MAPS\n", doit); 6265969Smckusick fs->fs_contigsumsize = i; 6365969Smckusick } else if (preen || 6465969Smckusick reply("CREATE CLUSTER MAPS")) { 6565969Smckusick if (preen) 6665969Smckusick pwarn("%sING CLUSTER MAPS\n", 6765969Smckusick doit); 6865969Smckusick fs->fs_cgsize = 6965969Smckusick fragroundup(fs, CGSIZE(fs)); 7065969Smckusick doinglevel1 = 1; 7165969Smckusick sbdirty(); 7265969Smckusick } 7365969Smckusick } 7465969Smckusick } 7565969Smckusick } 7639973Smckusick switch ((int)fs->fs_postblformat) { 7734141Smckusick 7834141Smckusick case FS_42POSTBLFMT: 7967669Smckusick basesize = (char *)(&ocg->cg_btot[0]) - 8067669Smckusick (char *)(&ocg->cg_firstfield); 8167669Smckusick sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]); 8234223Smckusick mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 8334141Smckusick (u_char *)&ocg->cg_iused[0]; 8434141Smckusick ocg->cg_magic = CG_MAGIC; 8534223Smckusick savednrpos = fs->fs_nrpos; 8634223Smckusick fs->fs_nrpos = 8; 8734141Smckusick break; 8834141Smckusick 8934141Smckusick case FS_DYNAMICPOSTBLFMT: 9034141Smckusick newcg->cg_btotoff = 9167669Smckusick &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield); 9234141Smckusick newcg->cg_boff = 9365969Smckusick newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 9434141Smckusick newcg->cg_iusedoff = newcg->cg_boff + 9565969Smckusick fs->fs_cpg * fs->fs_nrpos * sizeof(short); 9634141Smckusick newcg->cg_freeoff = 9765969Smckusick newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 9865969Smckusick if (fs->fs_contigsumsize <= 0) { 9965969Smckusick newcg->cg_nextfreeoff = newcg->cg_freeoff + 10065969Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); 10165969Smckusick } else { 10265969Smckusick newcg->cg_clustersumoff = newcg->cg_freeoff + 10365969Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) - 10465969Smckusick sizeof(long); 10565969Smckusick newcg->cg_clustersumoff = 10665969Smckusick roundup(newcg->cg_clustersumoff, sizeof(long)); 10765969Smckusick newcg->cg_clusteroff = newcg->cg_clustersumoff + 10865969Smckusick (fs->fs_contigsumsize + 1) * sizeof(long); 10965969Smckusick newcg->cg_nextfreeoff = newcg->cg_clusteroff + 11065969Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); 11165969Smckusick } 11234141Smckusick newcg->cg_magic = CG_MAGIC; 11367669Smckusick basesize = &newcg->cg_space[0] - 11467669Smckusick (u_char *)(&newcg->cg_firstfield); 11534141Smckusick sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 11634141Smckusick mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 11734141Smckusick break; 11834141Smckusick 11934141Smckusick default: 12034141Smckusick errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 12134223Smckusick fs->fs_postblformat); 12234141Smckusick } 12337099Smckusick bzero((char *)&idesc[0], sizeof idesc); 12454601Smckusick for (i = 0; i < 3; i++) { 12537099Smckusick idesc[i].id_type = ADDR; 12654601Smckusick if (doinglevel2) 12754601Smckusick idesc[i].id_fix = FIX; 12854601Smckusick } 12917937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 13040018Smckusick j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 13140018Smckusick for (i = fs->fs_size; i < j; i++) 13234141Smckusick setbmap(i); 13334223Smckusick for (c = 0; c < fs->fs_ncg; c++) { 13434223Smckusick getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 13534223Smckusick if (!cg_chkmagic(cg)) 13616267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 13734223Smckusick dbase = cgbase(fs, c); 13834223Smckusick dmax = dbase + fs->fs_fpg; 13934223Smckusick if (dmax > fs->fs_size) 14034223Smckusick dmax = fs->fs_size; 14156353Smckusick newcg->cg_time = cg->cg_time; 14217937Smckusick newcg->cg_cgx = c; 14334223Smckusick if (c == fs->fs_ncg - 1) 14434223Smckusick newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 14517937Smckusick else 14634223Smckusick newcg->cg_ncyl = fs->fs_cpg; 14717937Smckusick newcg->cg_ndblk = dmax - dbase; 14865969Smckusick if (fs->fs_contigsumsize > 0) 14965969Smckusick newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; 15017937Smckusick newcg->cg_cs.cs_ndir = 0; 15117937Smckusick newcg->cg_cs.cs_nffree = 0; 15217937Smckusick newcg->cg_cs.cs_nbfree = 0; 15334223Smckusick newcg->cg_cs.cs_nifree = fs->fs_ipg; 15434223Smckusick if (cg->cg_rotor < newcg->cg_ndblk) 15534223Smckusick newcg->cg_rotor = cg->cg_rotor; 15617937Smckusick else 15717937Smckusick newcg->cg_rotor = 0; 15834223Smckusick if (cg->cg_frotor < newcg->cg_ndblk) 15934223Smckusick newcg->cg_frotor = cg->cg_frotor; 16017937Smckusick else 16117937Smckusick newcg->cg_frotor = 0; 16234223Smckusick if (cg->cg_irotor < newcg->cg_niblk) 16334223Smckusick newcg->cg_irotor = cg->cg_irotor; 16417937Smckusick else 16517937Smckusick newcg->cg_irotor = 0; 16634141Smckusick bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 16744934Smckusick bzero((char *)&cg_blktot(newcg)[0], 16844934Smckusick (size_t)(sumsize + mapsize)); 16934223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 17034141Smckusick ocg->cg_magic = CG_MAGIC; 17134223Smckusick j = fs->fs_ipg * c; 17234223Smckusick for (i = 0; i < fs->fs_ipg; j++, i++) { 17317937Smckusick switch (statemap[j]) { 17417937Smckusick 17517937Smckusick case USTATE: 17617937Smckusick break; 17717937Smckusick 17817937Smckusick case DSTATE: 17917937Smckusick case DCLEAR: 18017937Smckusick case DFOUND: 18117937Smckusick newcg->cg_cs.cs_ndir++; 18217937Smckusick /* fall through */ 18317937Smckusick 18417937Smckusick case FSTATE: 18517937Smckusick case FCLEAR: 18617937Smckusick newcg->cg_cs.cs_nifree--; 18734141Smckusick setbit(cg_inosused(newcg), i); 18817937Smckusick break; 18926480Smckusick 19026480Smckusick default: 19126480Smckusick if (j < ROOTINO) 19226480Smckusick break; 19326480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 19426480Smckusick statemap[j], j); 19517937Smckusick } 19616267Smckusick } 19717937Smckusick if (c == 0) 19817937Smckusick for (i = 0; i < ROOTINO; i++) { 19934141Smckusick setbit(cg_inosused(newcg), i); 20017937Smckusick newcg->cg_cs.cs_nifree--; 20116267Smckusick } 20217937Smckusick for (i = 0, d = dbase; 20334141Smckusick d < dmax; 20434223Smckusick d += fs->fs_frag, i += fs->fs_frag) { 20517937Smckusick frags = 0; 20634223Smckusick for (j = 0; j < fs->fs_frag; j++) { 20739973Smckusick if (testbmap(d + j)) 20817937Smckusick continue; 20934141Smckusick setbit(cg_blksfree(newcg), i + j); 21017937Smckusick frags++; 21117937Smckusick } 21234223Smckusick if (frags == fs->fs_frag) { 21317937Smckusick newcg->cg_cs.cs_nbfree++; 21434223Smckusick j = cbtocylno(fs, i); 21534141Smckusick cg_blktot(newcg)[j]++; 21634223Smckusick cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 21765969Smckusick if (fs->fs_contigsumsize > 0) 21865969Smckusick setbit(cg_clustersfree(newcg), 21965969Smckusick i / fs->fs_frag); 22017937Smckusick } else if (frags > 0) { 22117937Smckusick newcg->cg_cs.cs_nffree += frags; 22234223Smckusick blk = blkmap(fs, cg_blksfree(newcg), i); 22351637Sbostic ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 22417937Smckusick } 22516267Smckusick } 22665969Smckusick if (fs->fs_contigsumsize > 0) { 22768014Smckusick int32_t *sump = cg_clustersum(newcg); 22865969Smckusick u_char *mapp = cg_clustersfree(newcg); 22965969Smckusick int map = *mapp++; 23065969Smckusick int bit = 1; 23165969Smckusick int run = 0; 23265969Smckusick 23365969Smckusick for (i = 0; i < newcg->cg_nclusterblks; i++) { 23465969Smckusick if ((map & bit) != 0) { 23565969Smckusick run++; 23665969Smckusick } else if (run != 0) { 23765969Smckusick if (run > fs->fs_contigsumsize) 23865969Smckusick run = fs->fs_contigsumsize; 23965969Smckusick sump[run]++; 24065969Smckusick run = 0; 24165969Smckusick } 24265969Smckusick if ((i & (NBBY - 1)) != (NBBY - 1)) { 24365969Smckusick bit <<= 1; 24465969Smckusick } else { 24565969Smckusick map = *mapp++; 24665969Smckusick bit = 1; 24765969Smckusick } 24865969Smckusick } 24965969Smckusick if (run != 0) { 25065969Smckusick if (run > fs->fs_contigsumsize) 25165969Smckusick run = fs->fs_contigsumsize; 25265969Smckusick sump[run]++; 25365969Smckusick } 25465969Smckusick } 25517937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 25617937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 25717937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 25817937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 25934223Smckusick cs = &fs->fs_cs(fs, c); 26034141Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 26137099Smckusick dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 26234141Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 26334141Smckusick sbdirty(); 26434141Smckusick } 26554601Smckusick if (doinglevel1) { 26644934Smckusick bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); 26734141Smckusick cgdirty(); 26834141Smckusick continue; 26934141Smckusick } 27034141Smckusick if (bcmp(cg_inosused(newcg), 27134223Smckusick cg_inosused(cg), mapsize) != 0 && 27237099Smckusick dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 27344934Smckusick bcopy(cg_inosused(newcg), cg_inosused(cg), 27444934Smckusick (size_t)mapsize); 27517937Smckusick cgdirty(); 27616267Smckusick } 27734223Smckusick if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 27834141Smckusick bcmp((char *)&cg_blktot(newcg)[0], 27934223Smckusick (char *)&cg_blktot(cg)[0], sumsize) != 0) && 28037099Smckusick dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 28144934Smckusick bcopy((char *)newcg, (char *)cg, (size_t)basesize); 28234141Smckusick bcopy((char *)&cg_blktot(newcg)[0], 28344934Smckusick (char *)&cg_blktot(cg)[0], (size_t)sumsize); 28417937Smckusick cgdirty(); 28516267Smckusick } 28616267Smckusick } 28734223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 28834223Smckusick fs->fs_nrpos = savednrpos; 28934223Smckusick if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 29037099Smckusick && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 29134223Smckusick bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 29234223Smckusick fs->fs_ronly = 0; 29334223Smckusick fs->fs_fmod = 0; 29417937Smckusick sbdirty(); 29516267Smckusick } 29616267Smckusick } 297