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*24699Smckusick static char sccsid[] = "@(#)setup.c 5.2 (Berkeley) 09/11/85"; 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 /* 9116268Smckusick * Set all possible fields that could differ, then do check 9216268Smckusick * of whole super block against an alternate super block. 9316268Smckusick * When an alternate super-block is specified this check is skipped. 9416268Smckusick */ 9516268Smckusick if (bflag) 9616268Smckusick goto sbok; 9721540Smckusick getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); 9821540Smckusick if (asblk.b_errs != NULL) 9916268Smckusick return (0); 10016268Smckusick altsblock.fs_link = sblock.fs_link; 10116268Smckusick altsblock.fs_rlink = sblock.fs_rlink; 10216268Smckusick altsblock.fs_time = sblock.fs_time; 10316268Smckusick altsblock.fs_cstotal = sblock.fs_cstotal; 10416268Smckusick altsblock.fs_cgrotor = sblock.fs_cgrotor; 10516268Smckusick altsblock.fs_fmod = sblock.fs_fmod; 10616268Smckusick altsblock.fs_clean = sblock.fs_clean; 10716268Smckusick altsblock.fs_ronly = sblock.fs_ronly; 10816268Smckusick altsblock.fs_flags = sblock.fs_flags; 10916268Smckusick altsblock.fs_maxcontig = sblock.fs_maxcontig; 11016268Smckusick altsblock.fs_minfree = sblock.fs_minfree; 111*24699Smckusick altsblock.fs_optim = sblock.fs_optim; 11216268Smckusick altsblock.fs_rotdelay = sblock.fs_rotdelay; 11316268Smckusick altsblock.fs_maxbpg = sblock.fs_maxbpg; 11416268Smckusick bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, 11516268Smckusick sizeof sblock.fs_csp); 11616268Smckusick bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, 11716268Smckusick sizeof sblock.fs_fsmnt); 11816268Smckusick if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) 11916268Smckusick { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); } 12016268Smckusick sbok: 12116268Smckusick fmax = sblock.fs_size; 12216268Smckusick imax = sblock.fs_ncg * sblock.fs_ipg; 12316268Smckusick /* 12416268Smckusick * read in the summary info. 12516268Smckusick */ 12616268Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 12716268Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 12816268Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 12916268Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size); 13016268Smckusick if (bread(&dfile, (char *)sblock.fs_csp[j], 13116268Smckusick fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 13221540Smckusick size) != 0) 13316268Smckusick return (0); 13416268Smckusick } 13516268Smckusick /* 13616268Smckusick * allocate and initialize the necessary maps 13716268Smckusick */ 13816268Smckusick bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 13916268Smckusick blockmap = calloc((unsigned)bmapsz, sizeof (char)); 14016268Smckusick if (blockmap == NULL) { 14116268Smckusick printf("cannot alloc %d bytes for blockmap\n", bmapsz); 14216268Smckusick goto badsb; 14316268Smckusick } 14416268Smckusick statemap = calloc((unsigned)(imax + 1), sizeof(char)); 14516268Smckusick if (statemap == NULL) { 14616268Smckusick printf("cannot alloc %d bytes for statemap\n", imax + 1); 14716268Smckusick goto badsb; 14816268Smckusick } 14916268Smckusick lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short)); 15016268Smckusick if (lncntp == NULL) { 15116268Smckusick printf("cannot alloc %d bytes for lncntp\n", 15216268Smckusick (imax + 1) * sizeof(short)); 15316268Smckusick goto badsb; 15416268Smckusick } 15516268Smckusick 15616268Smckusick return (1); 15716268Smckusick 15816268Smckusick badsb: 15916268Smckusick ckfini(); 16016268Smckusick return (0); 16116268Smckusick # undef altsblock 16216268Smckusick } 16316268Smckusick 16416268Smckusick badsb(s) 16516268Smckusick char *s; 16616268Smckusick { 16716268Smckusick 16816268Smckusick if (preen) 16916268Smckusick printf("%s: ", devname); 17016268Smckusick printf("BAD SUPER BLOCK: %s\n", s); 17116268Smckusick pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 17216268Smckusick pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 17316268Smckusick } 174