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