1*16268Smckusick #ifndef lint 2*16268Smckusick static char version[] = "@(#)setup.c 3.1 (Berkeley) 03/31/84"; 3*16268Smckusick #endif 4*16268Smckusick 5*16268Smckusick #include <sys/param.h> 6*16268Smckusick #include <sys/inode.h> 7*16268Smckusick #include <sys/fs.h> 8*16268Smckusick #include <sys/stat.h> 9*16268Smckusick #include "fsck.h" 10*16268Smckusick 11*16268Smckusick char *calloc(); 12*16268Smckusick 13*16268Smckusick setup(dev) 14*16268Smckusick char *dev; 15*16268Smckusick { 16*16268Smckusick dev_t rootdev; 17*16268Smckusick struct stat statb; 18*16268Smckusick daddr_t super = bflag ? bflag : SBLOCK; 19*16268Smckusick int i, j, c, d, cgd; 20*16268Smckusick long size; 21*16268Smckusick BUFAREA asblk; 22*16268Smckusick # define altsblock asblk.b_un.b_fs 23*16268Smckusick 24*16268Smckusick if (stat("/", &statb) < 0) 25*16268Smckusick errexit("Can't stat root\n"); 26*16268Smckusick rootdev = statb.st_dev; 27*16268Smckusick if (stat(dev, &statb) < 0) { 28*16268Smckusick error("Can't stat %s\n", dev); 29*16268Smckusick return (0); 30*16268Smckusick } 31*16268Smckusick rawflg = 0; 32*16268Smckusick if ((statb.st_mode & S_IFMT) == S_IFBLK) 33*16268Smckusick ; 34*16268Smckusick else if ((statb.st_mode & S_IFMT) == S_IFCHR) 35*16268Smckusick rawflg++; 36*16268Smckusick else { 37*16268Smckusick if (reply("file is not a block or character device; OK") == 0) 38*16268Smckusick return (0); 39*16268Smckusick } 40*16268Smckusick if (rootdev == statb.st_rdev) 41*16268Smckusick hotroot++; 42*16268Smckusick if ((dfile.rfdes = open(dev, 0)) < 0) { 43*16268Smckusick error("Can't open %s\n", dev); 44*16268Smckusick return (0); 45*16268Smckusick } 46*16268Smckusick if (preen == 0) 47*16268Smckusick printf("** %s", dev); 48*16268Smckusick if (nflag || (dfile.wfdes = open(dev, 1)) < 0) { 49*16268Smckusick dfile.wfdes = -1; 50*16268Smckusick if (preen) 51*16268Smckusick pfatal("NO WRITE ACCESS"); 52*16268Smckusick printf(" (NO WRITE)"); 53*16268Smckusick } 54*16268Smckusick if (preen == 0) 55*16268Smckusick printf("\n"); 56*16268Smckusick fixcg = 0; inosumbad = 0; offsumbad = 0; frsumbad = 0; sbsumbad = 0; 57*16268Smckusick dfile.mod = 0; 58*16268Smckusick n_files = n_blks = n_ffree = n_bfree = 0; 59*16268Smckusick muldup = enddup = &duplist[0]; 60*16268Smckusick badlnp = &badlncnt[0]; 61*16268Smckusick lfdir = 0; 62*16268Smckusick rplyflag = 0; 63*16268Smckusick initbarea(&sblk); 64*16268Smckusick initbarea(&fileblk); 65*16268Smckusick initbarea(&inoblk); 66*16268Smckusick initbarea(&cgblk); 67*16268Smckusick initbarea(&asblk); 68*16268Smckusick /* 69*16268Smckusick * Read in the super block and its summary info. 70*16268Smckusick */ 71*16268Smckusick if (bread(&dfile, (char *)&sblock, super, (long)SBSIZE) == 0) 72*16268Smckusick return (0); 73*16268Smckusick sblk.b_bno = super; 74*16268Smckusick sblk.b_size = SBSIZE; 75*16268Smckusick /* 76*16268Smckusick * run a few consistency checks of the super block 77*16268Smckusick */ 78*16268Smckusick if (sblock.fs_magic != FS_MAGIC) 79*16268Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 80*16268Smckusick if (sblock.fs_ncg < 1) 81*16268Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 82*16268Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 83*16268Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 84*16268Smckusick if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 85*16268Smckusick (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 86*16268Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 87*16268Smckusick if (sblock.fs_sbsize > SBSIZE) 88*16268Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 89*16268Smckusick /* 90*16268Smckusick * Set all possible fields that could differ, then do check 91*16268Smckusick * of whole super block against an alternate super block. 92*16268Smckusick * When an alternate super-block is specified this check is skipped. 93*16268Smckusick */ 94*16268Smckusick if (bflag) 95*16268Smckusick goto sbok; 96*16268Smckusick if (getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), 97*16268Smckusick sblock.fs_sbsize) == 0) 98*16268Smckusick return (0); 99*16268Smckusick altsblock.fs_link = sblock.fs_link; 100*16268Smckusick altsblock.fs_rlink = sblock.fs_rlink; 101*16268Smckusick altsblock.fs_time = sblock.fs_time; 102*16268Smckusick altsblock.fs_cstotal = sblock.fs_cstotal; 103*16268Smckusick altsblock.fs_cgrotor = sblock.fs_cgrotor; 104*16268Smckusick altsblock.fs_fmod = sblock.fs_fmod; 105*16268Smckusick altsblock.fs_clean = sblock.fs_clean; 106*16268Smckusick altsblock.fs_ronly = sblock.fs_ronly; 107*16268Smckusick altsblock.fs_flags = sblock.fs_flags; 108*16268Smckusick altsblock.fs_maxcontig = sblock.fs_maxcontig; 109*16268Smckusick altsblock.fs_minfree = sblock.fs_minfree; 110*16268Smckusick altsblock.fs_rotdelay = sblock.fs_rotdelay; 111*16268Smckusick altsblock.fs_maxbpg = sblock.fs_maxbpg; 112*16268Smckusick bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, 113*16268Smckusick sizeof sblock.fs_csp); 114*16268Smckusick bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, 115*16268Smckusick sizeof sblock.fs_fsmnt); 116*16268Smckusick if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) 117*16268Smckusick { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); } 118*16268Smckusick sbok: 119*16268Smckusick fmax = sblock.fs_size; 120*16268Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 121*16268Smckusick n_bad = cgsblock(&sblock, 0); /* boot block plus dedicated sblock */ 122*16268Smckusick /* 123*16268Smckusick * read in the summary info. 124*16268Smckusick */ 125*16268Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 126*16268Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 127*16268Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 128*16268Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size); 129*16268Smckusick if (bread(&dfile, (char *)sblock.fs_csp[j], 130*16268Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 131*16268Smckusick size) == 0) 132*16268Smckusick return (0); 133*16268Smckusick } 134*16268Smckusick /* 135*16268Smckusick * allocate and initialize the necessary maps 136*16268Smckusick */ 137*16268Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 138*16268Smckusick blockmap = calloc((unsigned)bmapsz, sizeof (char)); 139*16268Smckusick if (blockmap == NULL) { 140*16268Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 141*16268Smckusick goto badsb; 142*16268Smckusick } 143*16268Smckusick freemap = calloc((unsigned)bmapsz, sizeof (char)); 144*16268Smckusick if (freemap == NULL) { 145*16268Smckusick printf("cannot alloc %d bytes for freemap\n", bmapsz); 146*16268Smckusick goto badsb; 147*16268Smckusick } 148*16268Smckusick statemap = calloc((unsigned)(imax + 1), sizeof(char)); 149*16268Smckusick if (statemap == NULL) { 150*16268Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 151*16268Smckusick goto badsb; 152*16268Smckusick } 153*16268Smckusick lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short)); 154*16268Smckusick if (lncntp == NULL) { 155*16268Smckusick printf("cannot alloc %d bytes for lncntp\n", 156*16268Smckusick (imax + 1) * sizeof(short)); 157*16268Smckusick goto badsb; 158*16268Smckusick } 159*16268Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 160*16268Smckusick cgd = cgdmin(&sblock, c); 161*16268Smckusick if (c == 0) { 162*16268Smckusick d = cgbase(&sblock, c); 163*16268Smckusick cgd += howmany(sblock.fs_cssize, sblock.fs_fsize); 164*16268Smckusick } else 165*16268Smckusick d = cgsblock(&sblock, c); 166*16268Smckusick for (; d < cgd; d++) 167*16268Smckusick setbmap(d); 168*16268Smckusick } 169*16268Smckusick 170*16268Smckusick return (1); 171*16268Smckusick 172*16268Smckusick badsb: 173*16268Smckusick ckfini(); 174*16268Smckusick return (0); 175*16268Smckusick # undef altsblock 176*16268Smckusick } 177*16268Smckusick 178*16268Smckusick badsb(s) 179*16268Smckusick char *s; 180*16268Smckusick { 181*16268Smckusick 182*16268Smckusick if (preen) 183*16268Smckusick printf("%s: ", devname); 184*16268Smckusick printf("BAD SUPER BLOCK: %s\n", s); 185*16268Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 186*16268Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 187*16268Smckusick } 188