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*65969Smckusick static char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 02/02/94"; 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 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 3444934Smckusick bzero((char *)newcg, (size_t)fs->fs_cgsize); 3534223Smckusick newcg->cg_niblk = fs->fs_ipg; 36*65969Smckusick if (cvtlevel > 3) { 37*65969Smckusick if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { 38*65969Smckusick if (preen) 39*65969Smckusick pwarn("DELETING CLUSTERING MAPS\n"); 40*65969Smckusick if (preen || reply("DELETE CLUSTERING MAPS")) { 41*65969Smckusick fs->fs_contigsumsize = 0; 42*65969Smckusick doinglevel1 = 1; 43*65969Smckusick sbdirty(); 44*65969Smckusick } 45*65969Smckusick } 46*65969Smckusick if (fs->fs_maxcontig > 1) { 47*65969Smckusick char *doit = 0; 48*65969Smckusick 49*65969Smckusick if (fs->fs_contigsumsize < 1) { 50*65969Smckusick doit = "CREAT"; 51*65969Smckusick } else if (fs->fs_contigsumsize < fs->fs_maxcontig && 52*65969Smckusick fs->fs_contigsumsize < FS_MAXCONTIG) { 53*65969Smckusick doit = "EXPAND"; 54*65969Smckusick } 55*65969Smckusick if (doit) { 56*65969Smckusick i = fs->fs_contigsumsize; 57*65969Smckusick fs->fs_contigsumsize = 58*65969Smckusick MIN(fs->fs_maxcontig, FS_MAXCONTIG); 59*65969Smckusick if (CGSIZE(fs) > fs->fs_bsize) { 60*65969Smckusick pwarn("CANNOT %s CLUSTER MAPS\n", doit); 61*65969Smckusick fs->fs_contigsumsize = i; 62*65969Smckusick } else if (preen || 63*65969Smckusick reply("CREATE CLUSTER MAPS")) { 64*65969Smckusick if (preen) 65*65969Smckusick pwarn("%sING CLUSTER MAPS\n", 66*65969Smckusick doit); 67*65969Smckusick fs->fs_cgsize = 68*65969Smckusick fragroundup(fs, CGSIZE(fs)); 69*65969Smckusick doinglevel1 = 1; 70*65969Smckusick sbdirty(); 71*65969Smckusick } 72*65969Smckusick } 73*65969Smckusick } 74*65969Smckusick } 7539973Smckusick switch ((int)fs->fs_postblformat) { 7634141Smckusick 7734141Smckusick case FS_42POSTBLFMT: 7834141Smckusick basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 7934141Smckusick sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 8034223Smckusick mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 8134141Smckusick (u_char *)&ocg->cg_iused[0]; 8234141Smckusick ocg->cg_magic = CG_MAGIC; 8334223Smckusick savednrpos = fs->fs_nrpos; 8434223Smckusick fs->fs_nrpos = 8; 8534141Smckusick break; 8634141Smckusick 8734141Smckusick case FS_DYNAMICPOSTBLFMT: 8834141Smckusick newcg->cg_btotoff = 89*65969Smckusick &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 9034141Smckusick newcg->cg_boff = 91*65969Smckusick newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 9234141Smckusick newcg->cg_iusedoff = newcg->cg_boff + 93*65969Smckusick fs->fs_cpg * fs->fs_nrpos * sizeof(short); 9434141Smckusick newcg->cg_freeoff = 95*65969Smckusick newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 96*65969Smckusick if (fs->fs_contigsumsize <= 0) { 97*65969Smckusick newcg->cg_nextfreeoff = newcg->cg_freeoff + 98*65969Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); 99*65969Smckusick } else { 100*65969Smckusick newcg->cg_clustersumoff = newcg->cg_freeoff + 101*65969Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) - 102*65969Smckusick sizeof(long); 103*65969Smckusick newcg->cg_clustersumoff = 104*65969Smckusick roundup(newcg->cg_clustersumoff, sizeof(long)); 105*65969Smckusick newcg->cg_clusteroff = newcg->cg_clustersumoff + 106*65969Smckusick (fs->fs_contigsumsize + 1) * sizeof(long); 107*65969Smckusick newcg->cg_nextfreeoff = newcg->cg_clusteroff + 108*65969Smckusick howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); 109*65969Smckusick } 11034141Smckusick newcg->cg_magic = CG_MAGIC; 11134141Smckusick basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 11234141Smckusick sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 11334141Smckusick mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 11434141Smckusick break; 11534141Smckusick 11634141Smckusick default: 11734141Smckusick errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 11834223Smckusick fs->fs_postblformat); 11934141Smckusick } 12037099Smckusick bzero((char *)&idesc[0], sizeof idesc); 12154601Smckusick for (i = 0; i < 3; i++) { 12237099Smckusick idesc[i].id_type = ADDR; 12354601Smckusick if (doinglevel2) 12454601Smckusick idesc[i].id_fix = FIX; 12554601Smckusick } 12617937Smckusick bzero((char *)&cstotal, sizeof(struct csum)); 12740018Smckusick j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 12840018Smckusick for (i = fs->fs_size; i < j; i++) 12934141Smckusick setbmap(i); 13034223Smckusick for (c = 0; c < fs->fs_ncg; c++) { 13134223Smckusick getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 13234223Smckusick if (!cg_chkmagic(cg)) 13316267Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 13434223Smckusick dbase = cgbase(fs, c); 13534223Smckusick dmax = dbase + fs->fs_fpg; 13634223Smckusick if (dmax > fs->fs_size) 13734223Smckusick dmax = fs->fs_size; 13856353Smckusick newcg->cg_time = cg->cg_time; 13917937Smckusick newcg->cg_cgx = c; 14034223Smckusick if (c == fs->fs_ncg - 1) 14134223Smckusick newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 14217937Smckusick else 14334223Smckusick newcg->cg_ncyl = fs->fs_cpg; 14417937Smckusick newcg->cg_ndblk = dmax - dbase; 145*65969Smckusick if (fs->fs_contigsumsize > 0) 146*65969Smckusick newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; 14717937Smckusick newcg->cg_cs.cs_ndir = 0; 14817937Smckusick newcg->cg_cs.cs_nffree = 0; 14917937Smckusick newcg->cg_cs.cs_nbfree = 0; 15034223Smckusick newcg->cg_cs.cs_nifree = fs->fs_ipg; 15134223Smckusick if (cg->cg_rotor < newcg->cg_ndblk) 15234223Smckusick newcg->cg_rotor = cg->cg_rotor; 15317937Smckusick else 15417937Smckusick newcg->cg_rotor = 0; 15534223Smckusick if (cg->cg_frotor < newcg->cg_ndblk) 15634223Smckusick newcg->cg_frotor = cg->cg_frotor; 15717937Smckusick else 15817937Smckusick newcg->cg_frotor = 0; 15934223Smckusick if (cg->cg_irotor < newcg->cg_niblk) 16034223Smckusick newcg->cg_irotor = cg->cg_irotor; 16117937Smckusick else 16217937Smckusick newcg->cg_irotor = 0; 16334141Smckusick bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 16444934Smckusick bzero((char *)&cg_blktot(newcg)[0], 16544934Smckusick (size_t)(sumsize + mapsize)); 16634223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 16734141Smckusick ocg->cg_magic = CG_MAGIC; 16834223Smckusick j = fs->fs_ipg * c; 16934223Smckusick for (i = 0; i < fs->fs_ipg; j++, i++) { 17017937Smckusick switch (statemap[j]) { 17117937Smckusick 17217937Smckusick case USTATE: 17317937Smckusick break; 17417937Smckusick 17517937Smckusick case DSTATE: 17617937Smckusick case DCLEAR: 17717937Smckusick case DFOUND: 17817937Smckusick newcg->cg_cs.cs_ndir++; 17917937Smckusick /* fall through */ 18017937Smckusick 18117937Smckusick case FSTATE: 18217937Smckusick case FCLEAR: 18317937Smckusick newcg->cg_cs.cs_nifree--; 18434141Smckusick setbit(cg_inosused(newcg), i); 18517937Smckusick break; 18626480Smckusick 18726480Smckusick default: 18826480Smckusick if (j < ROOTINO) 18926480Smckusick break; 19026480Smckusick errexit("BAD STATE %d FOR INODE I=%d", 19126480Smckusick statemap[j], j); 19217937Smckusick } 19316267Smckusick } 19417937Smckusick if (c == 0) 19517937Smckusick for (i = 0; i < ROOTINO; i++) { 19634141Smckusick setbit(cg_inosused(newcg), i); 19717937Smckusick newcg->cg_cs.cs_nifree--; 19816267Smckusick } 19917937Smckusick for (i = 0, d = dbase; 20034141Smckusick d < dmax; 20134223Smckusick d += fs->fs_frag, i += fs->fs_frag) { 20217937Smckusick frags = 0; 20334223Smckusick for (j = 0; j < fs->fs_frag; j++) { 20439973Smckusick if (testbmap(d + j)) 20517937Smckusick continue; 20634141Smckusick setbit(cg_blksfree(newcg), i + j); 20717937Smckusick frags++; 20817937Smckusick } 20934223Smckusick if (frags == fs->fs_frag) { 21017937Smckusick newcg->cg_cs.cs_nbfree++; 21134223Smckusick j = cbtocylno(fs, i); 21234141Smckusick cg_blktot(newcg)[j]++; 21334223Smckusick cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 214*65969Smckusick if (fs->fs_contigsumsize > 0) 215*65969Smckusick setbit(cg_clustersfree(newcg), 216*65969Smckusick i / fs->fs_frag); 21717937Smckusick } else if (frags > 0) { 21817937Smckusick newcg->cg_cs.cs_nffree += frags; 21934223Smckusick blk = blkmap(fs, cg_blksfree(newcg), i); 22051637Sbostic ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 22117937Smckusick } 22216267Smckusick } 223*65969Smckusick if (fs->fs_contigsumsize > 0) { 224*65969Smckusick long *sump = cg_clustersum(newcg); 225*65969Smckusick u_char *mapp = cg_clustersfree(newcg); 226*65969Smckusick int map = *mapp++; 227*65969Smckusick int bit = 1; 228*65969Smckusick int run = 0; 229*65969Smckusick 230*65969Smckusick for (i = 0; i < newcg->cg_nclusterblks; i++) { 231*65969Smckusick if ((map & bit) != 0) { 232*65969Smckusick run++; 233*65969Smckusick } else if (run != 0) { 234*65969Smckusick if (run > fs->fs_contigsumsize) 235*65969Smckusick run = fs->fs_contigsumsize; 236*65969Smckusick sump[run]++; 237*65969Smckusick run = 0; 238*65969Smckusick } 239*65969Smckusick if ((i & (NBBY - 1)) != (NBBY - 1)) { 240*65969Smckusick bit <<= 1; 241*65969Smckusick } else { 242*65969Smckusick map = *mapp++; 243*65969Smckusick bit = 1; 244*65969Smckusick } 245*65969Smckusick } 246*65969Smckusick if (run != 0) { 247*65969Smckusick if (run > fs->fs_contigsumsize) 248*65969Smckusick run = fs->fs_contigsumsize; 249*65969Smckusick sump[run]++; 250*65969Smckusick } 251*65969Smckusick } 25217937Smckusick cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 25317937Smckusick cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 25417937Smckusick cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 25517937Smckusick cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 25634223Smckusick cs = &fs->fs_cs(fs, c); 25734141Smckusick if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 25837099Smckusick dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 25934141Smckusick bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 26034141Smckusick sbdirty(); 26134141Smckusick } 26254601Smckusick if (doinglevel1) { 26344934Smckusick bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); 26434141Smckusick cgdirty(); 26534141Smckusick continue; 26634141Smckusick } 26734141Smckusick if (bcmp(cg_inosused(newcg), 26834223Smckusick cg_inosused(cg), mapsize) != 0 && 26937099Smckusick dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 27044934Smckusick bcopy(cg_inosused(newcg), cg_inosused(cg), 27144934Smckusick (size_t)mapsize); 27217937Smckusick cgdirty(); 27316267Smckusick } 27434223Smckusick if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 27534141Smckusick bcmp((char *)&cg_blktot(newcg)[0], 27634223Smckusick (char *)&cg_blktot(cg)[0], sumsize) != 0) && 27737099Smckusick dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 27844934Smckusick bcopy((char *)newcg, (char *)cg, (size_t)basesize); 27934141Smckusick bcopy((char *)&cg_blktot(newcg)[0], 28044934Smckusick (char *)&cg_blktot(cg)[0], (size_t)sumsize); 28117937Smckusick cgdirty(); 28216267Smckusick } 28316267Smckusick } 28434223Smckusick if (fs->fs_postblformat == FS_42POSTBLFMT) 28534223Smckusick fs->fs_nrpos = savednrpos; 28634223Smckusick if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 28737099Smckusick && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 28834223Smckusick bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 28934223Smckusick fs->fs_ronly = 0; 29034223Smckusick fs->fs_fmod = 0; 29117937Smckusick sbdirty(); 29216267Smckusick } 29316267Smckusick } 294