122054Sdist /* 222054Sdist * Copyright (c) 1980 Regents of the University of California. 322054Sdist * All rights reserved. The Berkeley software License Agreement 422054Sdist * specifies the terms and conditions for redistribution. 522054Sdist */ 622054Sdist 716268Smckusick #ifndef lint 8*28213Smckusick static char sccsid[] = "@(#)setup.c 5.3 (Berkeley) 05/15/86"; 922054Sdist #endif not lint 1016268Smckusick 1116268Smckusick #include <sys/param.h> 1216268Smckusick #include <sys/inode.h> 1316268Smckusick #include <sys/fs.h> 1416268Smckusick #include <sys/stat.h> 1516268Smckusick #include "fsck.h" 1616268Smckusick 1716268Smckusick char *calloc(); 1816268Smckusick 1916268Smckusick setup(dev) 2016268Smckusick char *dev; 2116268Smckusick { 2216268Smckusick dev_t rootdev; 2316268Smckusick struct stat statb; 2416268Smckusick daddr_t super = bflag ? bflag : SBLOCK; 2517931Smckusick int i, j; 2616268Smckusick long size; 2716268Smckusick BUFAREA asblk; 2816268Smckusick # define altsblock asblk.b_un.b_fs 2916268Smckusick 3016268Smckusick if (stat("/", &statb) < 0) 3116268Smckusick errexit("Can't stat root\n"); 3216268Smckusick rootdev = statb.st_dev; 3316268Smckusick if (stat(dev, &statb) < 0) { 3417931Smckusick printf("Can't stat %s\n", dev); 3516268Smckusick return (0); 3616268Smckusick } 3716268Smckusick rawflg = 0; 3816268Smckusick if ((statb.st_mode & S_IFMT) == S_IFBLK) 3916268Smckusick ; 4016268Smckusick else if ((statb.st_mode & S_IFMT) == S_IFCHR) 4116268Smckusick rawflg++; 4216268Smckusick else { 4316268Smckusick if (reply("file is not a block or character device; OK") == 0) 4416268Smckusick return (0); 4516268Smckusick } 4616268Smckusick if (rootdev == statb.st_rdev) 4716268Smckusick hotroot++; 4816268Smckusick if ((dfile.rfdes = open(dev, 0)) < 0) { 4917931Smckusick printf("Can't open %s\n", dev); 5016268Smckusick return (0); 5116268Smckusick } 5216268Smckusick if (preen == 0) 5316268Smckusick printf("** %s", dev); 5416268Smckusick if (nflag || (dfile.wfdes = open(dev, 1)) < 0) { 5516268Smckusick dfile.wfdes = -1; 5616268Smckusick if (preen) 5716268Smckusick pfatal("NO WRITE ACCESS"); 5816268Smckusick printf(" (NO WRITE)"); 5916268Smckusick } 6016268Smckusick if (preen == 0) 6116268Smckusick printf("\n"); 6216268Smckusick dfile.mod = 0; 6316268Smckusick lfdir = 0; 6416268Smckusick initbarea(&sblk); 6516268Smckusick initbarea(&fileblk); 6616268Smckusick initbarea(&inoblk); 6716268Smckusick initbarea(&cgblk); 6816268Smckusick initbarea(&asblk); 6916268Smckusick /* 7016268Smckusick * Read in the super block and its summary info. 7116268Smckusick */ 7221540Smckusick if (bread(&dfile, (char *)&sblock, super, (long)SBSIZE) != 0) 7316268Smckusick return (0); 7416268Smckusick sblk.b_bno = super; 7516268Smckusick sblk.b_size = SBSIZE; 7616268Smckusick /* 7716268Smckusick * run a few consistency checks of the super block 7816268Smckusick */ 7916268Smckusick if (sblock.fs_magic != FS_MAGIC) 8016268Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 8116268Smckusick if (sblock.fs_ncg < 1) 8216268Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 8316268Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 8416268Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 8516268Smckusick if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 8616268Smckusick (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 8716268Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 8816268Smckusick if (sblock.fs_sbsize > SBSIZE) 8916268Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 9016268Smckusick /* 91*28213Smckusick * Check and potentially fix certain fields in the super block. 92*28213Smckusick */ 93*28213Smckusick if (sblock.fs_optim != FS_OPTTIME && sblock.fs_optim != FS_OPTSPACE) { 94*28213Smckusick pfatal("UNDEFINED OPTIMIZATION IN SUPERBLOCK"); 95*28213Smckusick if (reply("SET TO DEFAULT") == 1) { 96*28213Smckusick sblock.fs_optim = FS_OPTTIME; 97*28213Smckusick sbdirty(); 98*28213Smckusick } 99*28213Smckusick } 100*28213Smckusick if ((sblock.fs_minfree < 0 || sblock.fs_minfree > 99)) { 101*28213Smckusick pfatal("IMPOSSIBLE MINFREE=%d IN SUPERBLOCK", 102*28213Smckusick sblock.fs_minfree); 103*28213Smckusick if (reply("SET TO DEFAULT") == 1) { 104*28213Smckusick sblock.fs_minfree = 10; 105*28213Smckusick sbdirty(); 106*28213Smckusick } 107*28213Smckusick } 108*28213Smckusick /* 10916268Smckusick * Set all possible fields that could differ, then do check 11016268Smckusick * of whole super block against an alternate super block. 11116268Smckusick * When an alternate super-block is specified this check is skipped. 11216268Smckusick */ 11316268Smckusick if (bflag) 11416268Smckusick goto sbok; 11521540Smckusick getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); 11621540Smckusick if (asblk.b_errs != NULL) 11716268Smckusick return (0); 11816268Smckusick altsblock.fs_link = sblock.fs_link; 11916268Smckusick altsblock.fs_rlink = sblock.fs_rlink; 12016268Smckusick altsblock.fs_time = sblock.fs_time; 12116268Smckusick altsblock.fs_cstotal = sblock.fs_cstotal; 12216268Smckusick altsblock.fs_cgrotor = sblock.fs_cgrotor; 12316268Smckusick altsblock.fs_fmod = sblock.fs_fmod; 12416268Smckusick altsblock.fs_clean = sblock.fs_clean; 12516268Smckusick altsblock.fs_ronly = sblock.fs_ronly; 12616268Smckusick altsblock.fs_flags = sblock.fs_flags; 12716268Smckusick altsblock.fs_maxcontig = sblock.fs_maxcontig; 12816268Smckusick altsblock.fs_minfree = sblock.fs_minfree; 12924699Smckusick altsblock.fs_optim = sblock.fs_optim; 13016268Smckusick altsblock.fs_rotdelay = sblock.fs_rotdelay; 13116268Smckusick altsblock.fs_maxbpg = sblock.fs_maxbpg; 13216268Smckusick bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, 13316268Smckusick sizeof sblock.fs_csp); 13416268Smckusick bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, 13516268Smckusick sizeof sblock.fs_fsmnt); 13616268Smckusick if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) 13716268Smckusick { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); } 13816268Smckusick sbok: 13916268Smckusick fmax = sblock.fs_size; 14016268Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 14116268Smckusick /* 14216268Smckusick * read in the summary info. 14316268Smckusick */ 14416268Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 14516268Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 14616268Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 14716268Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size); 14816268Smckusick if (bread(&dfile, (char *)sblock.fs_csp[j], 14916268Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 15021540Smckusick size) != 0) 15116268Smckusick return (0); 15216268Smckusick } 15316268Smckusick /* 15416268Smckusick * allocate and initialize the necessary maps 15516268Smckusick */ 15616268Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 15716268Smckusick blockmap = calloc((unsigned)bmapsz, sizeof (char)); 15816268Smckusick if (blockmap == NULL) { 15916268Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 16016268Smckusick goto badsb; 16116268Smckusick } 16216268Smckusick statemap = calloc((unsigned)(imax + 1), sizeof(char)); 16316268Smckusick if (statemap == NULL) { 16416268Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 16516268Smckusick goto badsb; 16616268Smckusick } 16716268Smckusick lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short)); 16816268Smckusick if (lncntp == NULL) { 16916268Smckusick printf("cannot alloc %d bytes for lncntp\n", 17016268Smckusick (imax + 1) * sizeof(short)); 17116268Smckusick goto badsb; 17216268Smckusick } 17316268Smckusick 17416268Smckusick return (1); 17516268Smckusick 17616268Smckusick badsb: 17716268Smckusick ckfini(); 17816268Smckusick return (0); 17916268Smckusick # undef altsblock 18016268Smckusick } 18116268Smckusick 18216268Smckusick badsb(s) 18316268Smckusick char *s; 18416268Smckusick { 18516268Smckusick 18616268Smckusick if (preen) 18716268Smckusick printf("%s: ", devname); 18816268Smckusick printf("BAD SUPER BLOCK: %s\n", s); 18916268Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 19016268Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 19116268Smckusick } 192