pass5.c revision 1558
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1980, 1986, 1993 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * Redistribution and use in source and binary forms, with or without 61558Srgrimes * modification, are permitted provided that the following conditions 71558Srgrimes * are met: 81558Srgrimes * 1. Redistributions of source code must retain the above copyright 91558Srgrimes * notice, this list of conditions and the following disclaimer. 101558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 3. All advertising materials mentioning features or use of this software 141558Srgrimes * must display the following acknowledgement: 151558Srgrimes * This product includes software developed by the University of 161558Srgrimes * California, Berkeley and its contributors. 171558Srgrimes * 4. Neither the name of the University nor the names of its contributors 181558Srgrimes * may be used to endorse or promote products derived from this software 191558Srgrimes * without specific prior written permission. 201558Srgrimes * 211558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311558Srgrimes * SUCH DAMAGE. 321558Srgrimes */ 331558Srgrimes 341558Srgrimes#ifndef lint 351558Srgrimesstatic char sccsid[] = "@(#)pass5.c 8.2 (Berkeley) 2/2/94"; 361558Srgrimes#endif /* not lint */ 371558Srgrimes 381558Srgrimes#include <sys/param.h> 391558Srgrimes#include <sys/time.h> 401558Srgrimes#include <ufs/ufs/dinode.h> 411558Srgrimes#include <ufs/ffs/fs.h> 421558Srgrimes#include <string.h> 431558Srgrimes#include "fsck.h" 441558Srgrimes 451558Srgrimespass5() 461558Srgrimes{ 471558Srgrimes int c, blk, frags, basesize, sumsize, mapsize, savednrpos; 481558Srgrimes register struct fs *fs = &sblock; 491558Srgrimes register struct cg *cg = &cgrp; 501558Srgrimes daddr_t dbase, dmax; 511558Srgrimes register daddr_t d; 521558Srgrimes register long i, j; 531558Srgrimes struct csum *cs; 541558Srgrimes struct csum cstotal; 551558Srgrimes struct inodesc idesc[3]; 561558Srgrimes char buf[MAXBSIZE]; 571558Srgrimes register struct cg *newcg = (struct cg *)buf; 581558Srgrimes struct ocg *ocg = (struct ocg *)buf; 591558Srgrimes 601558Srgrimes bzero((char *)newcg, (size_t)fs->fs_cgsize); 611558Srgrimes newcg->cg_niblk = fs->fs_ipg; 621558Srgrimes if (cvtlevel > 3) { 631558Srgrimes if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) { 641558Srgrimes if (preen) 651558Srgrimes pwarn("DELETING CLUSTERING MAPS\n"); 661558Srgrimes if (preen || reply("DELETE CLUSTERING MAPS")) { 671558Srgrimes fs->fs_contigsumsize = 0; 681558Srgrimes doinglevel1 = 1; 691558Srgrimes sbdirty(); 701558Srgrimes } 711558Srgrimes } 721558Srgrimes if (fs->fs_maxcontig > 1) { 731558Srgrimes char *doit = 0; 741558Srgrimes 751558Srgrimes if (fs->fs_contigsumsize < 1) { 761558Srgrimes doit = "CREAT"; 771558Srgrimes } else if (fs->fs_contigsumsize < fs->fs_maxcontig && 781558Srgrimes fs->fs_contigsumsize < FS_MAXCONTIG) { 791558Srgrimes doit = "EXPAND"; 801558Srgrimes } 811558Srgrimes if (doit) { 821558Srgrimes i = fs->fs_contigsumsize; 831558Srgrimes fs->fs_contigsumsize = 841558Srgrimes MIN(fs->fs_maxcontig, FS_MAXCONTIG); 851558Srgrimes if (CGSIZE(fs) > fs->fs_bsize) { 861558Srgrimes pwarn("CANNOT %s CLUSTER MAPS\n", doit); 871558Srgrimes fs->fs_contigsumsize = i; 881558Srgrimes } else if (preen || 891558Srgrimes reply("CREATE CLUSTER MAPS")) { 901558Srgrimes if (preen) 911558Srgrimes pwarn("%sING CLUSTER MAPS\n", 921558Srgrimes doit); 931558Srgrimes fs->fs_cgsize = 941558Srgrimes fragroundup(fs, CGSIZE(fs)); 951558Srgrimes doinglevel1 = 1; 961558Srgrimes sbdirty(); 971558Srgrimes } 981558Srgrimes } 991558Srgrimes } 1001558Srgrimes } 1011558Srgrimes switch ((int)fs->fs_postblformat) { 1021558Srgrimes 1031558Srgrimes case FS_42POSTBLFMT: 1041558Srgrimes basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link); 1051558Srgrimes sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]); 1061558Srgrimes mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] - 1071558Srgrimes (u_char *)&ocg->cg_iused[0]; 1081558Srgrimes ocg->cg_magic = CG_MAGIC; 1091558Srgrimes savednrpos = fs->fs_nrpos; 1101558Srgrimes fs->fs_nrpos = 8; 1111558Srgrimes break; 1121558Srgrimes 1131558Srgrimes case FS_DYNAMICPOSTBLFMT: 1141558Srgrimes newcg->cg_btotoff = 1151558Srgrimes &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 1161558Srgrimes newcg->cg_boff = 1171558Srgrimes newcg->cg_btotoff + fs->fs_cpg * sizeof(long); 1181558Srgrimes newcg->cg_iusedoff = newcg->cg_boff + 1191558Srgrimes fs->fs_cpg * fs->fs_nrpos * sizeof(short); 1201558Srgrimes newcg->cg_freeoff = 1211558Srgrimes newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY); 1221558Srgrimes if (fs->fs_contigsumsize <= 0) { 1231558Srgrimes newcg->cg_nextfreeoff = newcg->cg_freeoff + 1241558Srgrimes howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY); 1251558Srgrimes } else { 1261558Srgrimes newcg->cg_clustersumoff = newcg->cg_freeoff + 1271558Srgrimes howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) - 1281558Srgrimes sizeof(long); 1291558Srgrimes newcg->cg_clustersumoff = 1301558Srgrimes roundup(newcg->cg_clustersumoff, sizeof(long)); 1311558Srgrimes newcg->cg_clusteroff = newcg->cg_clustersumoff + 1321558Srgrimes (fs->fs_contigsumsize + 1) * sizeof(long); 1331558Srgrimes newcg->cg_nextfreeoff = newcg->cg_clusteroff + 1341558Srgrimes howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY); 1351558Srgrimes } 1361558Srgrimes newcg->cg_magic = CG_MAGIC; 1371558Srgrimes basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); 1381558Srgrimes sumsize = newcg->cg_iusedoff - newcg->cg_btotoff; 1391558Srgrimes mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff; 1401558Srgrimes break; 1411558Srgrimes 1421558Srgrimes default: 1431558Srgrimes errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", 1441558Srgrimes fs->fs_postblformat); 1451558Srgrimes } 1461558Srgrimes bzero((char *)&idesc[0], sizeof idesc); 1471558Srgrimes for (i = 0; i < 3; i++) { 1481558Srgrimes idesc[i].id_type = ADDR; 1491558Srgrimes if (doinglevel2) 1501558Srgrimes idesc[i].id_fix = FIX; 1511558Srgrimes } 1521558Srgrimes bzero((char *)&cstotal, sizeof(struct csum)); 1531558Srgrimes j = blknum(fs, fs->fs_size + fs->fs_frag - 1); 1541558Srgrimes for (i = fs->fs_size; i < j; i++) 1551558Srgrimes setbmap(i); 1561558Srgrimes for (c = 0; c < fs->fs_ncg; c++) { 1571558Srgrimes getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize); 1581558Srgrimes if (!cg_chkmagic(cg)) 1591558Srgrimes pfatal("CG %d: BAD MAGIC NUMBER\n", c); 1601558Srgrimes dbase = cgbase(fs, c); 1611558Srgrimes dmax = dbase + fs->fs_fpg; 1621558Srgrimes if (dmax > fs->fs_size) 1631558Srgrimes dmax = fs->fs_size; 1641558Srgrimes newcg->cg_time = cg->cg_time; 1651558Srgrimes newcg->cg_cgx = c; 1661558Srgrimes if (c == fs->fs_ncg - 1) 1671558Srgrimes newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg; 1681558Srgrimes else 1691558Srgrimes newcg->cg_ncyl = fs->fs_cpg; 1701558Srgrimes newcg->cg_ndblk = dmax - dbase; 1711558Srgrimes if (fs->fs_contigsumsize > 0) 1721558Srgrimes newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag; 1731558Srgrimes newcg->cg_cs.cs_ndir = 0; 1741558Srgrimes newcg->cg_cs.cs_nffree = 0; 1751558Srgrimes newcg->cg_cs.cs_nbfree = 0; 1761558Srgrimes newcg->cg_cs.cs_nifree = fs->fs_ipg; 1771558Srgrimes if (cg->cg_rotor < newcg->cg_ndblk) 1781558Srgrimes newcg->cg_rotor = cg->cg_rotor; 1791558Srgrimes else 1801558Srgrimes newcg->cg_rotor = 0; 1811558Srgrimes if (cg->cg_frotor < newcg->cg_ndblk) 1821558Srgrimes newcg->cg_frotor = cg->cg_frotor; 1831558Srgrimes else 1841558Srgrimes newcg->cg_frotor = 0; 1851558Srgrimes if (cg->cg_irotor < newcg->cg_niblk) 1861558Srgrimes newcg->cg_irotor = cg->cg_irotor; 1871558Srgrimes else 1881558Srgrimes newcg->cg_irotor = 0; 1891558Srgrimes bzero((char *)&newcg->cg_frsum[0], sizeof newcg->cg_frsum); 1901558Srgrimes bzero((char *)&cg_blktot(newcg)[0], 1911558Srgrimes (size_t)(sumsize + mapsize)); 1921558Srgrimes if (fs->fs_postblformat == FS_42POSTBLFMT) 1931558Srgrimes ocg->cg_magic = CG_MAGIC; 1941558Srgrimes j = fs->fs_ipg * c; 1951558Srgrimes for (i = 0; i < fs->fs_ipg; j++, i++) { 1961558Srgrimes switch (statemap[j]) { 1971558Srgrimes 1981558Srgrimes case USTATE: 1991558Srgrimes break; 2001558Srgrimes 2011558Srgrimes case DSTATE: 2021558Srgrimes case DCLEAR: 2031558Srgrimes case DFOUND: 2041558Srgrimes newcg->cg_cs.cs_ndir++; 2051558Srgrimes /* fall through */ 2061558Srgrimes 2071558Srgrimes case FSTATE: 2081558Srgrimes case FCLEAR: 2091558Srgrimes newcg->cg_cs.cs_nifree--; 2101558Srgrimes setbit(cg_inosused(newcg), i); 2111558Srgrimes break; 2121558Srgrimes 2131558Srgrimes default: 2141558Srgrimes if (j < ROOTINO) 2151558Srgrimes break; 2161558Srgrimes errexit("BAD STATE %d FOR INODE I=%d", 2171558Srgrimes statemap[j], j); 2181558Srgrimes } 2191558Srgrimes } 2201558Srgrimes if (c == 0) 2211558Srgrimes for (i = 0; i < ROOTINO; i++) { 2221558Srgrimes setbit(cg_inosused(newcg), i); 2231558Srgrimes newcg->cg_cs.cs_nifree--; 2241558Srgrimes } 2251558Srgrimes for (i = 0, d = dbase; 2261558Srgrimes d < dmax; 2271558Srgrimes d += fs->fs_frag, i += fs->fs_frag) { 2281558Srgrimes frags = 0; 2291558Srgrimes for (j = 0; j < fs->fs_frag; j++) { 2301558Srgrimes if (testbmap(d + j)) 2311558Srgrimes continue; 2321558Srgrimes setbit(cg_blksfree(newcg), i + j); 2331558Srgrimes frags++; 2341558Srgrimes } 2351558Srgrimes if (frags == fs->fs_frag) { 2361558Srgrimes newcg->cg_cs.cs_nbfree++; 2371558Srgrimes j = cbtocylno(fs, i); 2381558Srgrimes cg_blktot(newcg)[j]++; 2391558Srgrimes cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++; 2401558Srgrimes if (fs->fs_contigsumsize > 0) 2411558Srgrimes setbit(cg_clustersfree(newcg), 2421558Srgrimes i / fs->fs_frag); 2431558Srgrimes } else if (frags > 0) { 2441558Srgrimes newcg->cg_cs.cs_nffree += frags; 2451558Srgrimes blk = blkmap(fs, cg_blksfree(newcg), i); 2461558Srgrimes ffs_fragacct(fs, blk, newcg->cg_frsum, 1); 2471558Srgrimes } 2481558Srgrimes } 2491558Srgrimes if (fs->fs_contigsumsize > 0) { 2501558Srgrimes long *sump = cg_clustersum(newcg); 2511558Srgrimes u_char *mapp = cg_clustersfree(newcg); 2521558Srgrimes int map = *mapp++; 2531558Srgrimes int bit = 1; 2541558Srgrimes int run = 0; 2551558Srgrimes 2561558Srgrimes for (i = 0; i < newcg->cg_nclusterblks; i++) { 2571558Srgrimes if ((map & bit) != 0) { 2581558Srgrimes run++; 2591558Srgrimes } else if (run != 0) { 2601558Srgrimes if (run > fs->fs_contigsumsize) 2611558Srgrimes run = fs->fs_contigsumsize; 2621558Srgrimes sump[run]++; 2631558Srgrimes run = 0; 2641558Srgrimes } 2651558Srgrimes if ((i & (NBBY - 1)) != (NBBY - 1)) { 2661558Srgrimes bit <<= 1; 2671558Srgrimes } else { 2681558Srgrimes map = *mapp++; 2691558Srgrimes bit = 1; 2701558Srgrimes } 2711558Srgrimes } 2721558Srgrimes if (run != 0) { 2731558Srgrimes if (run > fs->fs_contigsumsize) 2741558Srgrimes run = fs->fs_contigsumsize; 2751558Srgrimes sump[run]++; 2761558Srgrimes } 2771558Srgrimes } 2781558Srgrimes cstotal.cs_nffree += newcg->cg_cs.cs_nffree; 2791558Srgrimes cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; 2801558Srgrimes cstotal.cs_nifree += newcg->cg_cs.cs_nifree; 2811558Srgrimes cstotal.cs_ndir += newcg->cg_cs.cs_ndir; 2821558Srgrimes cs = &fs->fs_cs(fs, c); 2831558Srgrimes if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && 2841558Srgrimes dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 2851558Srgrimes bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); 2861558Srgrimes sbdirty(); 2871558Srgrimes } 2881558Srgrimes if (doinglevel1) { 2891558Srgrimes bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize); 2901558Srgrimes cgdirty(); 2911558Srgrimes continue; 2921558Srgrimes } 2931558Srgrimes if (bcmp(cg_inosused(newcg), 2941558Srgrimes cg_inosused(cg), mapsize) != 0 && 2951558Srgrimes dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) { 2961558Srgrimes bcopy(cg_inosused(newcg), cg_inosused(cg), 2971558Srgrimes (size_t)mapsize); 2981558Srgrimes cgdirty(); 2991558Srgrimes } 3001558Srgrimes if ((bcmp((char *)newcg, (char *)cg, basesize) != 0 || 3011558Srgrimes bcmp((char *)&cg_blktot(newcg)[0], 3021558Srgrimes (char *)&cg_blktot(cg)[0], sumsize) != 0) && 3031558Srgrimes dofix(&idesc[2], "SUMMARY INFORMATION BAD")) { 3041558Srgrimes bcopy((char *)newcg, (char *)cg, (size_t)basesize); 3051558Srgrimes bcopy((char *)&cg_blktot(newcg)[0], 3061558Srgrimes (char *)&cg_blktot(cg)[0], (size_t)sumsize); 3071558Srgrimes cgdirty(); 3081558Srgrimes } 3091558Srgrimes } 3101558Srgrimes if (fs->fs_postblformat == FS_42POSTBLFMT) 3111558Srgrimes fs->fs_nrpos = savednrpos; 3121558Srgrimes if (bcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0 3131558Srgrimes && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { 3141558Srgrimes bcopy((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs); 3151558Srgrimes fs->fs_ronly = 0; 3161558Srgrimes fs->fs_fmod = 0; 3171558Srgrimes sbdirty(); 3181558Srgrimes } 3191558Srgrimes} 320