116268Smckusick #ifndef lint 2*17931Smckusick static char version[] = "@(#)setup.c 3.2 (Berkeley) 02/07/85"; 316268Smckusick #endif 416268Smckusick 516268Smckusick #include <sys/param.h> 616268Smckusick #include <sys/inode.h> 716268Smckusick #include <sys/fs.h> 816268Smckusick #include <sys/stat.h> 916268Smckusick #include "fsck.h" 1016268Smckusick 1116268Smckusick char *calloc(); 1216268Smckusick 1316268Smckusick setup(dev) 1416268Smckusick char *dev; 1516268Smckusick { 1616268Smckusick dev_t rootdev; 1716268Smckusick struct stat statb; 1816268Smckusick daddr_t super = bflag ? bflag : SBLOCK; 19*17931Smckusick int i, j; 2016268Smckusick long size; 2116268Smckusick BUFAREA asblk; 2216268Smckusick # define altsblock asblk.b_un.b_fs 2316268Smckusick 2416268Smckusick if (stat("/", &statb) < 0) 2516268Smckusick errexit("Can't stat root\n"); 2616268Smckusick rootdev = statb.st_dev; 2716268Smckusick if (stat(dev, &statb) < 0) { 28*17931Smckusick printf("Can't stat %s\n", dev); 2916268Smckusick return (0); 3016268Smckusick } 3116268Smckusick rawflg = 0; 3216268Smckusick if ((statb.st_mode & S_IFMT) == S_IFBLK) 3316268Smckusick ; 3416268Smckusick else if ((statb.st_mode & S_IFMT) == S_IFCHR) 3516268Smckusick rawflg++; 3616268Smckusick else { 3716268Smckusick if (reply("file is not a block or character device; OK") == 0) 3816268Smckusick return (0); 3916268Smckusick } 4016268Smckusick if (rootdev == statb.st_rdev) 4116268Smckusick hotroot++; 4216268Smckusick if ((dfile.rfdes = open(dev, 0)) < 0) { 43*17931Smckusick printf("Can't open %s\n", dev); 4416268Smckusick return (0); 4516268Smckusick } 4616268Smckusick if (preen == 0) 4716268Smckusick printf("** %s", dev); 4816268Smckusick if (nflag || (dfile.wfdes = open(dev, 1)) < 0) { 4916268Smckusick dfile.wfdes = -1; 5016268Smckusick if (preen) 5116268Smckusick pfatal("NO WRITE ACCESS"); 5216268Smckusick printf(" (NO WRITE)"); 5316268Smckusick } 5416268Smckusick if (preen == 0) 5516268Smckusick printf("\n"); 5616268Smckusick fixcg = 0; inosumbad = 0; offsumbad = 0; frsumbad = 0; sbsumbad = 0; 5716268Smckusick dfile.mod = 0; 5816268Smckusick n_files = n_blks = n_ffree = n_bfree = 0; 5916268Smckusick muldup = enddup = &duplist[0]; 6016268Smckusick badlnp = &badlncnt[0]; 6116268Smckusick lfdir = 0; 6216268Smckusick initbarea(&sblk); 6316268Smckusick initbarea(&fileblk); 6416268Smckusick initbarea(&inoblk); 6516268Smckusick initbarea(&cgblk); 6616268Smckusick initbarea(&asblk); 6716268Smckusick /* 6816268Smckusick * Read in the super block and its summary info. 6916268Smckusick */ 7016268Smckusick if (bread(&dfile, (char *)&sblock, super, (long)SBSIZE) == 0) 7116268Smckusick return (0); 7216268Smckusick sblk.b_bno = super; 7316268Smckusick sblk.b_size = SBSIZE; 7416268Smckusick /* 7516268Smckusick * run a few consistency checks of the super block 7616268Smckusick */ 7716268Smckusick if (sblock.fs_magic != FS_MAGIC) 7816268Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 7916268Smckusick if (sblock.fs_ncg < 1) 8016268Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 8116268Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 8216268Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 8316268Smckusick if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 8416268Smckusick (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 8516268Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 8616268Smckusick if (sblock.fs_sbsize > SBSIZE) 8716268Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 8816268Smckusick /* 8916268Smckusick * Set all possible fields that could differ, then do check 9016268Smckusick * of whole super block against an alternate super block. 9116268Smckusick * When an alternate super-block is specified this check is skipped. 9216268Smckusick */ 9316268Smckusick if (bflag) 9416268Smckusick goto sbok; 9516268Smckusick if (getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), 9616268Smckusick sblock.fs_sbsize) == 0) 9716268Smckusick return (0); 9816268Smckusick altsblock.fs_link = sblock.fs_link; 9916268Smckusick altsblock.fs_rlink = sblock.fs_rlink; 10016268Smckusick altsblock.fs_time = sblock.fs_time; 10116268Smckusick altsblock.fs_cstotal = sblock.fs_cstotal; 10216268Smckusick altsblock.fs_cgrotor = sblock.fs_cgrotor; 10316268Smckusick altsblock.fs_fmod = sblock.fs_fmod; 10416268Smckusick altsblock.fs_clean = sblock.fs_clean; 10516268Smckusick altsblock.fs_ronly = sblock.fs_ronly; 10616268Smckusick altsblock.fs_flags = sblock.fs_flags; 10716268Smckusick altsblock.fs_maxcontig = sblock.fs_maxcontig; 10816268Smckusick altsblock.fs_minfree = sblock.fs_minfree; 10916268Smckusick altsblock.fs_rotdelay = sblock.fs_rotdelay; 11016268Smckusick altsblock.fs_maxbpg = sblock.fs_maxbpg; 11116268Smckusick bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, 11216268Smckusick sizeof sblock.fs_csp); 11316268Smckusick bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, 11416268Smckusick sizeof sblock.fs_fsmnt); 11516268Smckusick if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) 11616268Smckusick { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); } 11716268Smckusick sbok: 11816268Smckusick fmax = sblock.fs_size; 11916268Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 12016268Smckusick n_bad = cgsblock(&sblock, 0); /* boot block plus dedicated sblock */ 12116268Smckusick /* 12216268Smckusick * read in the summary info. 12316268Smckusick */ 12416268Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 12516268Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 12616268Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 12716268Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size); 12816268Smckusick if (bread(&dfile, (char *)sblock.fs_csp[j], 12916268Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 13016268Smckusick size) == 0) 13116268Smckusick return (0); 13216268Smckusick } 13316268Smckusick /* 13416268Smckusick * allocate and initialize the necessary maps 13516268Smckusick */ 13616268Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 13716268Smckusick blockmap = calloc((unsigned)bmapsz, sizeof (char)); 13816268Smckusick if (blockmap == NULL) { 13916268Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 14016268Smckusick goto badsb; 14116268Smckusick } 14216268Smckusick freemap = calloc((unsigned)bmapsz, sizeof (char)); 14316268Smckusick if (freemap == NULL) { 14416268Smckusick printf("cannot alloc %d bytes for freemap\n", bmapsz); 14516268Smckusick goto badsb; 14616268Smckusick } 14716268Smckusick statemap = calloc((unsigned)(imax + 1), sizeof(char)); 14816268Smckusick if (statemap == NULL) { 14916268Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 15016268Smckusick goto badsb; 15116268Smckusick } 15216268Smckusick lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short)); 15316268Smckusick if (lncntp == NULL) { 15416268Smckusick printf("cannot alloc %d bytes for lncntp\n", 15516268Smckusick (imax + 1) * sizeof(short)); 15616268Smckusick goto badsb; 15716268Smckusick } 15816268Smckusick 15916268Smckusick return (1); 16016268Smckusick 16116268Smckusick badsb: 16216268Smckusick ckfini(); 16316268Smckusick return (0); 16416268Smckusick # undef altsblock 16516268Smckusick } 16616268Smckusick 16716268Smckusick badsb(s) 16816268Smckusick char *s; 16916268Smckusick { 17016268Smckusick 17116268Smckusick if (preen) 17216268Smckusick printf("%s: ", devname); 17316268Smckusick printf("BAD SUPER BLOCK: %s\n", s); 17416268Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 17516268Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 17616268Smckusick } 177