116268Smckusick #ifndef lint 2*21540Smckusick static char version[] = "@(#)setup.c 3.4 (Berkeley) 05/31/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; 1917931Smckusick 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) { 2817931Smckusick 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) { 4317931Smckusick 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 dfile.mod = 0; 5716268Smckusick muldup = enddup = &duplist[0]; 5816268Smckusick badlnp = &badlncnt[0]; 5916268Smckusick lfdir = 0; 6016268Smckusick initbarea(&sblk); 6116268Smckusick initbarea(&fileblk); 6216268Smckusick initbarea(&inoblk); 6316268Smckusick initbarea(&cgblk); 6416268Smckusick initbarea(&asblk); 6516268Smckusick /* 6616268Smckusick * Read in the super block and its summary info. 6716268Smckusick */ 68*21540Smckusick if (bread(&dfile, (char *)&sblock, super, (long)SBSIZE) != 0) 6916268Smckusick return (0); 7016268Smckusick sblk.b_bno = super; 7116268Smckusick sblk.b_size = SBSIZE; 7216268Smckusick /* 7316268Smckusick * run a few consistency checks of the super block 7416268Smckusick */ 7516268Smckusick if (sblock.fs_magic != FS_MAGIC) 7616268Smckusick { badsb("MAGIC NUMBER WRONG"); return (0); } 7716268Smckusick if (sblock.fs_ncg < 1) 7816268Smckusick { badsb("NCG OUT OF RANGE"); return (0); } 7916268Smckusick if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 8016268Smckusick { badsb("CPG OUT OF RANGE"); return (0); } 8116268Smckusick if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 8216268Smckusick (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 8316268Smckusick { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 8416268Smckusick if (sblock.fs_sbsize > SBSIZE) 8516268Smckusick { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 8616268Smckusick /* 8716268Smckusick * Set all possible fields that could differ, then do check 8816268Smckusick * of whole super block against an alternate super block. 8916268Smckusick * When an alternate super-block is specified this check is skipped. 9016268Smckusick */ 9116268Smckusick if (bflag) 9216268Smckusick goto sbok; 93*21540Smckusick getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); 94*21540Smckusick if (asblk.b_errs != NULL) 9516268Smckusick return (0); 9616268Smckusick altsblock.fs_link = sblock.fs_link; 9716268Smckusick altsblock.fs_rlink = sblock.fs_rlink; 9816268Smckusick altsblock.fs_time = sblock.fs_time; 9916268Smckusick altsblock.fs_cstotal = sblock.fs_cstotal; 10016268Smckusick altsblock.fs_cgrotor = sblock.fs_cgrotor; 10116268Smckusick altsblock.fs_fmod = sblock.fs_fmod; 10216268Smckusick altsblock.fs_clean = sblock.fs_clean; 10316268Smckusick altsblock.fs_ronly = sblock.fs_ronly; 10416268Smckusick altsblock.fs_flags = sblock.fs_flags; 10516268Smckusick altsblock.fs_maxcontig = sblock.fs_maxcontig; 10616268Smckusick altsblock.fs_minfree = sblock.fs_minfree; 10716268Smckusick altsblock.fs_rotdelay = sblock.fs_rotdelay; 10816268Smckusick altsblock.fs_maxbpg = sblock.fs_maxbpg; 10916268Smckusick bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, 11016268Smckusick sizeof sblock.fs_csp); 11116268Smckusick bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, 11216268Smckusick sizeof sblock.fs_fsmnt); 11316268Smckusick if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) 11416268Smckusick { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); } 11516268Smckusick sbok: 11616268Smckusick fmax = sblock.fs_size; 11716268Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 11816268Smckusick /* 11916268Smckusick * read in the summary info. 12016268Smckusick */ 12116268Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 12216268Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 12316268Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 12416268Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size); 12516268Smckusick if (bread(&dfile, (char *)sblock.fs_csp[j], 12616268Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 127*21540Smckusick size) != 0) 12816268Smckusick return (0); 12916268Smckusick } 13016268Smckusick /* 13116268Smckusick * allocate and initialize the necessary maps 13216268Smckusick */ 13316268Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 13416268Smckusick blockmap = calloc((unsigned)bmapsz, sizeof (char)); 13516268Smckusick if (blockmap == NULL) { 13616268Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 13716268Smckusick goto badsb; 13816268Smckusick } 13916268Smckusick statemap = calloc((unsigned)(imax + 1), sizeof(char)); 14016268Smckusick if (statemap == NULL) { 14116268Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 14216268Smckusick goto badsb; 14316268Smckusick } 14416268Smckusick lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short)); 14516268Smckusick if (lncntp == NULL) { 14616268Smckusick printf("cannot alloc %d bytes for lncntp\n", 14716268Smckusick (imax + 1) * sizeof(short)); 14816268Smckusick goto badsb; 14916268Smckusick } 15016268Smckusick 15116268Smckusick return (1); 15216268Smckusick 15316268Smckusick badsb: 15416268Smckusick ckfini(); 15516268Smckusick return (0); 15616268Smckusick # undef altsblock 15716268Smckusick } 15816268Smckusick 15916268Smckusick badsb(s) 16016268Smckusick char *s; 16116268Smckusick { 16216268Smckusick 16316268Smckusick if (preen) 16416268Smckusick printf("%s: ", devname); 16516268Smckusick printf("BAD SUPER BLOCK: %s\n", s); 16616268Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 16716268Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 16816268Smckusick } 169