1 /* 2 * Copyright (c) 1980 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)pass5.c 5.5 (Berkeley) 05/07/88"; 9 #endif not lint 10 11 #include <sys/param.h> 12 #include <sys/inode.h> 13 #include <sys/fs.h> 14 #include "fsck.h" 15 16 pass5() 17 { 18 int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 19 register struct fs *fs = &sblock; 20 register struct cg *cg = &cgrp; 21 daddr_t dbase, dmax; 22 register daddr_t d; 23 register long i, j; 24 struct csum *cs; 25 time_t now; 26 struct csum cstotal; 27 struct inodesc idesc; 28 char buf[MAXBSIZE]; 29 register struct cg *newcg = (struct cg *)buf; 30 struct ocg *ocg = (struct ocg *)buf; 31 32 bzero((char *)newcg, fs->fs_cgsize); 33 newcg->cg_niblk = fs->fs_ipg; 34 switch (fs->fs_postblformat) { 35 36 case FS_42POSTBLFMT: 37 basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 38 sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 39 mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 40 (u_char *)&ocg->cg_iused[0]; 41 ocg->cg_magic = CG_MAGIC; 42 savednrpos = fs->fs_nrpos; 43 fs->fs_nrpos = 8; 44 break; 45 46 case FS_DYNAMICPOSTBLFMT: 47 newcg->cg_btotoff = 48 &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 49 newcg->cg_boff = 50 newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 51 newcg->cg_iusedoff = newcg->cg_boff + 52 fs->fs_cpg * fs->fs_nrpos * sizeof(short); 53 newcg->cg_freeoff = 54 newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 55 newcg->cg_nextfreeoff = newcg->cg_freeoff + 56 howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), 57 NBBY); 58 newcg->cg_magic = CG_MAGIC; 59 basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 60 sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 61 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 62 break; 63 64 default: 65 errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 66 fs->fs_postblformat); 67 } 68 bzero((char *)&idesc, sizeof(struct inodesc)); 69 idesc.id_type = ADDR; 70 bzero((char *)&cstotal, sizeof(struct csum)); 71 (void)time(&now); 72 for (i = fs->fs_size; i < fragroundup(fs, fs->fs_size); i++) 73 setbmap(i); 74 for (c = 0; c < fs->fs_ncg; c++) { 75 getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 76 if (!cg_chkmagic(cg)) 77 pfatal("CG %d: BAD MAGIC NUMBER\n", c); 78 dbase = cgbase(fs, c); 79 dmax = dbase + fs->fs_fpg; 80 if (dmax > fs->fs_size) 81 dmax = fs->fs_size; 82 if (now > cg->cg_time) 83 newcg->cg_time = cg->cg_time; 84 else 85 newcg->cg_time = now; 86 newcg->cg_cgx = c; 87 if (c == fs->fs_ncg - 1) 88 newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 89 else 90 newcg->cg_ncyl = fs->fs_cpg; 91 newcg->cg_ndblk = dmax - dbase; 92 newcg->cg_cs.cs_ndir = 0; 93 newcg->cg_cs.cs_nffree = 0; 94 newcg->cg_cs.cs_nbfree = 0; 95 newcg->cg_cs.cs_nifree = fs->fs_ipg; 96 if (cg->cg_rotor < newcg->cg_ndblk) 97 newcg->cg_rotor = cg->cg_rotor; 98 else 99 newcg->cg_rotor = 0; 100 if (cg->cg_frotor < newcg->cg_ndblk) 101 newcg->cg_frotor = cg->cg_frotor; 102 else 103 newcg->cg_frotor = 0; 104 if (cg->cg_irotor < newcg->cg_niblk) 105 newcg->cg_irotor = cg->cg_irotor; 106 else 107 newcg->cg_irotor = 0; 108 bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 109 bzero((char *)&cg_blktot(newcg)[0], sumsize + mapsize); 110 if (fs->fs_postblformat == FS_42POSTBLFMT) 111 ocg->cg_magic = CG_MAGIC; 112 j = fs->fs_ipg * c; 113 for (i = 0; i < fs->fs_ipg; j++, i++) { 114 switch (statemap[j]) { 115 116 case USTATE: 117 break; 118 119 case DSTATE: 120 case DCLEAR: 121 case DFOUND: 122 newcg->cg_cs.cs_ndir++; 123 /* fall through */ 124 125 case FSTATE: 126 case FCLEAR: 127 newcg->cg_cs.cs_nifree--; 128 setbit(cg_inosused(newcg), i); 129 break; 130 131 default: 132 if (j < ROOTINO) 133 break; 134 errexit("BAD STATE %d FOR INODE I=%d", 135 statemap[j], j); 136 } 137 } 138 if (c == 0) 139 for (i = 0; i < ROOTINO; i++) { 140 setbit(cg_inosused(newcg), i); 141 newcg->cg_cs.cs_nifree--; 142 } 143 for (i = 0, d = dbase; 144 d < dmax; 145 d += fs->fs_frag, i += fs->fs_frag) { 146 frags = 0; 147 for (j = 0; j < fs->fs_frag; j++) { 148 if (getbmap(d + j)) 149 continue; 150 setbit(cg_blksfree(newcg), i + j); 151 frags++; 152 } 153 if (frags == fs->fs_frag) { 154 newcg->cg_cs.cs_nbfree++; 155 j = cbtocylno(fs, i); 156 cg_blktot(newcg)[j]++; 157 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 158 } else if (frags > 0) { 159 newcg->cg_cs.cs_nffree += frags; 160 blk = blkmap(fs, cg_blksfree(newcg), i); 161 fragacct(fs, blk, newcg->cg_frsum, 1); 162 } 163 } 164 cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 165 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 166 cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 167 cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 168 cs = &fs->fs_cs(fs, c); 169 if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 170 dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 171 bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 172 sbdirty(); 173 } 174 if (cvtflag) { 175 bcopy((char *)newcg, (char *)cg, fs->fs_cgsize); 176 cgdirty(); 177 continue; 178 } 179 if (bcmp(cg_inosused(newcg), 180 cg_inosused(cg), mapsize) != 0 && 181 dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { 182 bcopy(cg_inosused(newcg), cg_inosused(cg), mapsize); 183 cgdirty(); 184 } 185 if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 186 bcmp((char *)&cg_blktot(newcg)[0], 187 (char *)&cg_blktot(cg)[0], sumsize) != 0) && 188 dofix(&idesc, "SUMMARY INFORMATION BAD")) { 189 bcopy((char *)newcg, (char *)cg, basesize); 190 bcopy((char *)&cg_blktot(newcg)[0], 191 (char *)&cg_blktot(cg)[0], sumsize); 192 cgdirty(); 193 } 194 } 195 if (fs->fs_postblformat == FS_42POSTBLFMT) 196 fs->fs_nrpos = savednrpos; 197 if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 198 && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 199 bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 200 fs->fs_ronly = 0; 201 fs->fs_fmod = 0; 202 sbdirty(); 203 } 204 } 205