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 char sccsid[] = "from: @(#)pass5.c 8.2 (Berkeley) 2/2/94";*/ 36 static char *rcsid = "$Id: pass5.c,v 1.11 1994/12/18 15:55:41 cgd Exp $"; 37 #endif /* not lint */ 38 39 #include <sys/param.h> 40 #include <sys/time.h> 41 #include <ufs/ufs/dinode.h> 42 #include <ufs/ffs/fs.h> 43 #include <string.h> 44 #include "fsck.h" 45 #include "extern.h" 46 47 void 48 pass5() 49 { 50 int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 51 register struct fs *fs = &sblock; 52 register struct cg *cg = &cgrp; 53 daddr_t dbase, dmax; 54 register daddr_t d; 55 register long i, j; 56 struct csum *cs; 57 struct csum cstotal; 58 struct inodesc idesc[3]; 59 char buf[MAXBSIZE]; 60 register struct cg *newcg = (struct cg *)buf; 61 struct ocg *ocg = (struct ocg *)buf; 62 63 memset(newcg, 0, (size_t)fs->fs_cgsize); 64 newcg->cg_niblk = fs->fs_ipg; 65 if (cvtlevel > 3) { 66 if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { 67 if (preen) 68 pwarn("DELETING CLUSTERING MAPS\n"); 69 if (preen || reply("DELETE CLUSTERING MAPS")) { 70 fs->fs_contigsumsize = 0; 71 doinglevel1 = 1; 72 sbdirty(); 73 } 74 } 75 if (fs->fs_maxcontig > 1) { 76 char *doit = 0; 77 78 if (fs->fs_contigsumsize < 1) { 79 doit = "CREAT"; 80 } else if (fs->fs_contigsumsize < fs->fs_maxcontig && 81 fs->fs_contigsumsize < FS_MAXCONTIG) { 82 doit = "EXPAND"; 83 } 84 if (doit) { 85 i = fs->fs_contigsumsize; 86 fs->fs_contigsumsize = 87 MIN(fs->fs_maxcontig, FS_MAXCONTIG); 88 if (CGSIZE(fs) > fs->fs_bsize) { 89 pwarn("CANNOT %s CLUSTER MAPS\n", doit); 90 fs->fs_contigsumsize = i; 91 } else if (preen || 92 reply("CREATE CLUSTER MAPS")) { 93 if (preen) 94 pwarn("%sING CLUSTER MAPS\n", 95 doit); 96 fs->fs_cgsize = 97 fragroundup(fs, CGSIZE(fs)); 98 doinglevel1 = 1; 99 sbdirty(); 100 } 101 } 102 } 103 } 104 switch ((int)fs->fs_postblformat) { 105 106 case FS_42POSTBLFMT: 107 basesize = (char *)(&ocg->cg_btot[0]) - 108 (char *)(&ocg->cg_firstfield); 109 sumsize = (char *)&ocg->cg_iused[0] - 110 (char *)(&ocg->cg_btot[0]); 111 mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 112 (u_char *)&ocg->cg_iused[0]; 113 ocg->cg_magic = CG_MAGIC; 114 savednrpos = fs->fs_nrpos; 115 fs->fs_nrpos = 8; 116 break; 117 118 case FS_DYNAMICPOSTBLFMT: 119 newcg->cg_btotoff = 120 &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield); 121 newcg->cg_boff = 122 newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 123 newcg->cg_iusedoff = newcg->cg_boff + 124 fs->fs_cpg * fs->fs_nrpos * sizeof(short); 125 newcg->cg_freeoff = 126 newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 127 if (fs->fs_contigsumsize <= 0) { 128 newcg->cg_nextfreeoff = newcg->cg_freeoff + 129 howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); 130 } else { 131 newcg->cg_clustersumoff = newcg->cg_freeoff + 132 howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) - 133 sizeof(long); 134 newcg->cg_clustersumoff = 135 roundup(newcg->cg_clustersumoff, sizeof(long)); 136 newcg->cg_clusteroff = newcg->cg_clustersumoff + 137 (fs->fs_contigsumsize + 1) * sizeof(long); 138 newcg->cg_nextfreeoff = newcg->cg_clusteroff + 139 howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); 140 } 141 newcg->cg_magic = CG_MAGIC; 142 basesize = &newcg->cg_space[0] - 143 (u_char *)(&newcg->cg_firstfield); 144 sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 145 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 146 break; 147 148 default: 149 errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 150 fs->fs_postblformat); 151 } 152 memset(&idesc[0], 0, sizeof idesc); 153 for (i = 0; i < 3; i++) { 154 idesc[i].id_type = ADDR; 155 if (doinglevel2) 156 idesc[i].id_fix = FIX; 157 } 158 memset(&cstotal, 0, sizeof(struct csum)); 159 j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 160 for (i = fs->fs_size; i < j; i++) 161 setbmap(i); 162 for (c = 0; c < fs->fs_ncg; c++) { 163 getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 164 if (!cg_chkmagic(cg)) 165 pfatal("CG %d: BAD MAGIC NUMBER\n", c); 166 dbase = cgbase(fs, c); 167 dmax = dbase + fs->fs_fpg; 168 if (dmax > fs->fs_size) 169 dmax = fs->fs_size; 170 newcg->cg_time = cg->cg_time; 171 newcg->cg_cgx = c; 172 if (c == fs->fs_ncg - 1) 173 newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 174 else 175 newcg->cg_ncyl = fs->fs_cpg; 176 newcg->cg_ndblk = dmax - dbase; 177 if (fs->fs_contigsumsize > 0) 178 newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; 179 newcg->cg_cs.cs_ndir = 0; 180 newcg->cg_cs.cs_nffree = 0; 181 newcg->cg_cs.cs_nbfree = 0; 182 newcg->cg_cs.cs_nifree = fs->fs_ipg; 183 if (cg->cg_rotor < newcg->cg_ndblk) 184 newcg->cg_rotor = cg->cg_rotor; 185 else 186 newcg->cg_rotor = 0; 187 if (cg->cg_frotor < newcg->cg_ndblk) 188 newcg->cg_frotor = cg->cg_frotor; 189 else 190 newcg->cg_frotor = 0; 191 if (cg->cg_irotor < newcg->cg_niblk) 192 newcg->cg_irotor = cg->cg_irotor; 193 else 194 newcg->cg_irotor = 0; 195 memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum); 196 memset(&cg_blktot(newcg)[0], 0, 197 (size_t)(sumsize + mapsize)); 198 if (fs->fs_postblformat == FS_42POSTBLFMT) 199 ocg->cg_magic = CG_MAGIC; 200 j = fs->fs_ipg * c; 201 for (i = 0; i < fs->fs_ipg; j++, i++) { 202 switch (statemap[j]) { 203 204 case USTATE: 205 break; 206 207 case DSTATE: 208 case DCLEAR: 209 case DFOUND: 210 newcg->cg_cs.cs_ndir++; 211 /* fall through */ 212 213 case FSTATE: 214 case FCLEAR: 215 newcg->cg_cs.cs_nifree--; 216 setbit(cg_inosused(newcg), i); 217 break; 218 219 default: 220 if (j < ROOTINO) 221 break; 222 errexit("BAD STATE %d FOR INODE I=%d", 223 statemap[j], j); 224 } 225 } 226 if (c == 0) 227 for (i = 0; i < ROOTINO; i++) { 228 setbit(cg_inosused(newcg), i); 229 newcg->cg_cs.cs_nifree--; 230 } 231 for (i = 0, d = dbase; 232 d < dmax; 233 d += fs->fs_frag, i += fs->fs_frag) { 234 frags = 0; 235 for (j = 0; j < fs->fs_frag; j++) { 236 if (testbmap(d + j)) 237 continue; 238 setbit(cg_blksfree(newcg), i + j); 239 frags++; 240 } 241 if (frags == fs->fs_frag) { 242 newcg->cg_cs.cs_nbfree++; 243 j = cbtocylno(fs, i); 244 cg_blktot(newcg)[j]++; 245 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 246 if (fs->fs_contigsumsize > 0) 247 setbit(cg_clustersfree(newcg), 248 i / fs->fs_frag); 249 } else if (frags > 0) { 250 newcg->cg_cs.cs_nffree += frags; 251 blk = blkmap(fs, cg_blksfree(newcg), i); 252 ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 253 } 254 } 255 if (fs->fs_contigsumsize > 0) { 256 int32_t *sump = cg_clustersum(newcg); 257 u_char *mapp = cg_clustersfree(newcg); 258 int map = *mapp++; 259 int bit = 1; 260 int run = 0; 261 262 for (i = 0; i < newcg->cg_nclusterblks; i++) { 263 if ((map & bit) != 0) { 264 run++; 265 } else if (run != 0) { 266 if (run > fs->fs_contigsumsize) 267 run = fs->fs_contigsumsize; 268 sump[run]++; 269 run = 0; 270 } 271 if ((i & (NBBY - 1)) != (NBBY - 1)) { 272 bit <<= 1; 273 } else { 274 map = *mapp++; 275 bit = 1; 276 } 277 } 278 if (run != 0) { 279 if (run > fs->fs_contigsumsize) 280 run = fs->fs_contigsumsize; 281 sump[run]++; 282 } 283 } 284 cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 285 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 286 cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 287 cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 288 cs = &fs->fs_cs(fs, c); 289 if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 && 290 dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 291 memcpy(cs, &newcg->cg_cs, sizeof *cs); 292 sbdirty(); 293 } 294 if (doinglevel1) { 295 memcpy(cg, newcg, (size_t)fs->fs_cgsize); 296 cgdirty(); 297 continue; 298 } 299 if (memcmp(cg_inosused(newcg), 300 cg_inosused(cg), mapsize) != 0 && 301 dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 302 memcpy(cg_inosused(cg), cg_inosused(newcg), 303 (size_t)mapsize); 304 cgdirty(); 305 } 306 if ((memcmp(newcg, cg, basesize) != 0 || 307 memcmp(&cg_blktot(newcg)[0], 308 &cg_blktot(cg)[0], sumsize) != 0) && 309 dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 310 memcpy(cg, newcg, (size_t)basesize); 311 memcpy(&cg_blktot(cg)[0], 312 &cg_blktot(newcg)[0], (size_t)sumsize); 313 cgdirty(); 314 } 315 } 316 if (fs->fs_postblformat == FS_42POSTBLFMT) 317 fs->fs_nrpos = savednrpos; 318 if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0 319 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 320 memcpy(&fs->fs_cstotal, &cstotal, sizeof *cs); 321 fs->fs_ronly = 0; 322 fs->fs_fmod = 0; 323 sbdirty(); 324 } 325 } 326