1 /* 2 * Copyright (c) 1980, 1986, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #ifndef lint 35 static const char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94"; 36 #endif /* not lint */ 37 38 #include <sys/param.h> 39 #include <sys/time.h> 40 #include <ufs/ufs/dinode.h> 41 #include <ufs/ffs/fs.h> 42 #include <stdio.h> 43 #include <string.h> 44 #include "fsck.h" 45 46 void 47 pass5() 48 { 49 int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0; 50 register struct fs *fs = &sblock; 51 register struct cg *cg = &cgrp; 52 daddr_t dbase, dmax; 53 register daddr_t d; 54 register long i, j; 55 struct csum *cs; 56 struct csum cstotal; 57 struct inodesc idesc[3]; 58 char buf[MAXBSIZE]; 59 register struct cg *newcg = (struct cg *)buf; 60 struct ocg *ocg = (struct ocg *)buf; 61 62 bzero((char *)newcg, (size_t)fs->fs_cgsize); 63 newcg->cg_niblk = fs->fs_ipg; 64 if (cvtlevel > 3) { 65 if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { 66 if (preen) 67 pwarn("DELETING CLUSTERING MAPS\n"); 68 if (preen || reply("DELETE CLUSTERING MAPS")) { 69 fs->fs_contigsumsize = 0; 70 doinglevel1 = 1; 71 sbdirty(); 72 } 73 } 74 if (fs->fs_maxcontig > 1) { 75 char *doit = 0; 76 77 if (fs->fs_contigsumsize < 1) { 78 doit = "CREAT"; 79 } else if (fs->fs_contigsumsize < fs->fs_maxcontig && 80 fs->fs_contigsumsize < FS_MAXCONTIG) { 81 doit = "EXPAND"; 82 } 83 if (doit) { 84 i = fs->fs_contigsumsize; 85 fs->fs_contigsumsize = 86 MIN(fs->fs_maxcontig, FS_MAXCONTIG); 87 if (CGSIZE(fs) > fs->fs_bsize) { 88 pwarn("CANNOT %s CLUSTER MAPS\n", doit); 89 fs->fs_contigsumsize = i; 90 } else if (preen || 91 reply("CREATE CLUSTER MAPS")) { 92 if (preen) 93 pwarn("%sING CLUSTER MAPS\n", 94 doit); 95 fs->fs_cgsize = 96 fragroundup(fs, CGSIZE(fs)); 97 doinglevel1 = 1; 98 sbdirty(); 99 } 100 } 101 } 102 } 103 switch ((int)fs->fs_postblformat) { 104 105 case FS_42POSTBLFMT: 106 basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 107 sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 108 mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 109 (u_char *)&ocg->cg_iused[0]; 110 ocg->cg_magic = CG_MAGIC; 111 savednrpos = fs->fs_nrpos; 112 fs->fs_nrpos = 8; 113 break; 114 115 case FS_DYNAMICPOSTBLFMT: 116 newcg->cg_btotoff = 117 &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 118 newcg->cg_boff = 119 newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 120 newcg->cg_iusedoff = newcg->cg_boff + 121 fs->fs_cpg * fs->fs_nrpos * sizeof(short); 122 newcg->cg_freeoff = 123 newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 124 if (fs->fs_contigsumsize <= 0) { 125 newcg->cg_nextfreeoff = newcg->cg_freeoff + 126 howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); 127 } else { 128 newcg->cg_clustersumoff = newcg->cg_freeoff + 129 howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) - 130 sizeof(long); 131 newcg->cg_clustersumoff = 132 roundup(newcg->cg_clustersumoff, sizeof(long)); 133 newcg->cg_clusteroff = newcg->cg_clustersumoff + 134 (fs->fs_contigsumsize + 1) * sizeof(long); 135 newcg->cg_nextfreeoff = newcg->cg_clusteroff + 136 howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); 137 } 138 newcg->cg_magic = CG_MAGIC; 139 basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 140 sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 141 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 142 break; 143 144 default: 145 errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 146 fs->fs_postblformat); 147 } 148 bzero((char *)&idesc[0], sizeof idesc); 149 for (i = 0; i < 3; i++) { 150 idesc[i].id_type = ADDR; 151 if (doinglevel2) 152 idesc[i].id_fix = FIX; 153 } 154 bzero((char *)&cstotal, sizeof(struct csum)); 155 j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 156 for (i = fs->fs_size; i < j; i++) 157 setbmap(i); 158 for (c = 0; c < fs->fs_ncg; c++) { 159 getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 160 if (!cg_chkmagic(cg)) 161 pfatal("CG %d: BAD MAGIC NUMBER\n", c); 162 dbase = cgbase(fs, c); 163 dmax = dbase + fs->fs_fpg; 164 if (dmax > fs->fs_size) 165 dmax = fs->fs_size; 166 newcg->cg_time = cg->cg_time; 167 newcg->cg_cgx = c; 168 if (c == fs->fs_ncg - 1) 169 newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 170 else 171 newcg->cg_ncyl = fs->fs_cpg; 172 newcg->cg_ndblk = dmax - dbase; 173 if (fs->fs_contigsumsize > 0) 174 newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; 175 newcg->cg_cs.cs_ndir = 0; 176 newcg->cg_cs.cs_nffree = 0; 177 newcg->cg_cs.cs_nbfree = 0; 178 newcg->cg_cs.cs_nifree = fs->fs_ipg; 179 if (cg->cg_rotor < newcg->cg_ndblk) 180 newcg->cg_rotor = cg->cg_rotor; 181 else 182 newcg->cg_rotor = 0; 183 if (cg->cg_frotor < newcg->cg_ndblk) 184 newcg->cg_frotor = cg->cg_frotor; 185 else 186 newcg->cg_frotor = 0; 187 if (cg->cg_irotor < newcg->cg_niblk) 188 newcg->cg_irotor = cg->cg_irotor; 189 else 190 newcg->cg_irotor = 0; 191 bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 192 bzero((char *)&cg_blktot(newcg)[0], 193 (size_t)(sumsize + mapsize)); 194 if (fs->fs_postblformat == FS_42POSTBLFMT) 195 ocg->cg_magic = CG_MAGIC; 196 j = fs->fs_ipg * c; 197 for (i = 0; i < fs->fs_ipg; j++, i++) { 198 switch (statemap[j]) { 199 200 case USTATE: 201 break; 202 203 case DSTATE: 204 case DCLEAR: 205 case DFOUND: 206 newcg->cg_cs.cs_ndir++; 207 /* fall through */ 208 209 case FSTATE: 210 case FCLEAR: 211 newcg->cg_cs.cs_nifree--; 212 setbit(cg_inosused(newcg), i); 213 break; 214 215 default: 216 if (j < ROOTINO) 217 break; 218 errexit("BAD STATE %d FOR INODE I=%d", 219 statemap[j], j); 220 } 221 } 222 if (c == 0) 223 for (i = 0; i < ROOTINO; i++) { 224 setbit(cg_inosused(newcg), i); 225 newcg->cg_cs.cs_nifree--; 226 } 227 for (i = 0, d = dbase; 228 d < dmax; 229 d += fs->fs_frag, i += fs->fs_frag) { 230 frags = 0; 231 for (j = 0; j < fs->fs_frag; j++) { 232 if (testbmap(d + j)) 233 continue; 234 setbit(cg_blksfree(newcg), i + j); 235 frags++; 236 } 237 if (frags == fs->fs_frag) { 238 newcg->cg_cs.cs_nbfree++; 239 j = cbtocylno(fs, i); 240 cg_blktot(newcg)[j]++; 241 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 242 if (fs->fs_contigsumsize > 0) 243 setbit(cg_clustersfree(newcg), 244 i / fs->fs_frag); 245 } else if (frags > 0) { 246 newcg->cg_cs.cs_nffree += frags; 247 blk = blkmap(fs, cg_blksfree(newcg), i); 248 ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 249 } 250 } 251 if (fs->fs_contigsumsize > 0) { 252 long *sump = cg_clustersum(newcg); 253 u_char *mapp = cg_clustersfree(newcg); 254 int map = *mapp++; 255 int bit = 1; 256 int run = 0; 257 258 for (i = 0; i < newcg->cg_nclusterblks; i++) { 259 if ((map & bit) != 0) { 260 run++; 261 } else if (run != 0) { 262 if (run > fs->fs_contigsumsize) 263 run = fs->fs_contigsumsize; 264 sump[run]++; 265 run = 0; 266 } 267 if ((i & (NBBY - 1)) != (NBBY - 1)) { 268 bit <<= 1; 269 } else { 270 map = *mapp++; 271 bit = 1; 272 } 273 } 274 if (run != 0) { 275 if (run > fs->fs_contigsumsize) 276 run = fs->fs_contigsumsize; 277 sump[run]++; 278 } 279 } 280 cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 281 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 282 cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 283 cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 284 cs = &fs->fs_cs(fs, c); 285 if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 286 dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 287 bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 288 sbdirty(); 289 } 290 if (doinglevel1) { 291 bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); 292 cgdirty(); 293 continue; 294 } 295 if (bcmp(cg_inosused(newcg), 296 cg_inosused(cg), mapsize) != 0 && 297 dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 298 bcopy(cg_inosused(newcg), cg_inosused(cg), 299 (size_t)mapsize); 300 cgdirty(); 301 } 302 if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 303 bcmp((char *)&cg_blktot(newcg)[0], 304 (char *)&cg_blktot(cg)[0], sumsize) != 0) && 305 dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 306 bcopy((char *)newcg, (char *)cg, (size_t)basesize); 307 bcopy((char *)&cg_blktot(newcg)[0], 308 (char *)&cg_blktot(cg)[0], (size_t)sumsize); 309 cgdirty(); 310 } 311 } 312 if (fs->fs_postblformat == FS_42POSTBLFMT) 313 fs->fs_nrpos = savednrpos; 314 if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 315 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 316 bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 317 fs->fs_ronly = 0; 318 fs->fs_fmod = 0; 319 sbdirty(); 320 } 321 if (fs->fs_clean == 0) { 322 pwarn("CLEAN FLAG NOT SET IN SUPERBLOCK"); 323 if (preen) 324 printf(" (FIXED)\n"); 325 if (preen || reply("FIX") == 1) { 326 fs->fs_clean = 1; 327 sbdirty(); 328 } 329 } 330 } 331