1 #ifndef lint 2 static char version[] = "@(#)setup.c 3.6 (Berkeley) 06/02/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 lfdir = 0; 58 initbarea(&sblk); 59 initbarea(&fileblk); 60 initbarea(&inoblk); 61 initbarea(&cgblk); 62 initbarea(&asblk); 63 /* 64 * Read in the super block and its summary info. 65 */ 66 if (bread(&dfile, (char *)&sblock, super, (long)SBSIZE) != 0) 67 return (0); 68 sblk.b_bno = super; 69 sblk.b_size = SBSIZE; 70 /* 71 * run a few consistency checks of the super block 72 */ 73 if (sblock.fs_magic != FS_MAGIC) 74 { badsb("MAGIC NUMBER WRONG"); return (0); } 75 if (sblock.fs_ncg < 1) 76 { badsb("NCG OUT OF RANGE"); return (0); } 77 if (sblock.fs_cpg < 1 || sblock.fs_cpg > MAXCPG) 78 { badsb("CPG OUT OF RANGE"); return (0); } 79 if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl || 80 (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl) 81 { badsb("NCYL DOES NOT JIVE WITH NCG*CPG"); return (0); } 82 if (sblock.fs_sbsize > SBSIZE) 83 { badsb("SIZE PREPOSTEROUSLY LARGE"); return (0); } 84 /* 85 * Set all possible fields that could differ, then do check 86 * of whole super block against an alternate super block. 87 * When an alternate super-block is specified this check is skipped. 88 */ 89 if (bflag) 90 goto sbok; 91 getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize); 92 if (asblk.b_errs != NULL) 93 return (0); 94 altsblock.fs_link = sblock.fs_link; 95 altsblock.fs_rlink = sblock.fs_rlink; 96 altsblock.fs_time = sblock.fs_time; 97 altsblock.fs_cstotal = sblock.fs_cstotal; 98 altsblock.fs_cgrotor = sblock.fs_cgrotor; 99 altsblock.fs_fmod = sblock.fs_fmod; 100 altsblock.fs_clean = sblock.fs_clean; 101 altsblock.fs_ronly = sblock.fs_ronly; 102 altsblock.fs_flags = sblock.fs_flags; 103 altsblock.fs_maxcontig = sblock.fs_maxcontig; 104 altsblock.fs_minfree = sblock.fs_minfree; 105 altsblock.fs_rotdelay = sblock.fs_rotdelay; 106 altsblock.fs_maxbpg = sblock.fs_maxbpg; 107 bcopy((char *)sblock.fs_csp, (char *)altsblock.fs_csp, 108 sizeof sblock.fs_csp); 109 bcopy((char *)sblock.fs_fsmnt, (char *)altsblock.fs_fsmnt, 110 sizeof sblock.fs_fsmnt); 111 if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) 112 { badsb("TRASHED VALUES IN SUPER BLOCK"); return (0); } 113 sbok: 114 fmax = sblock.fs_size; 115 imax = sblock.fs_ncg * sblock.fs_ipg; 116 /* 117 * read in the summary info. 118 */ 119 for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 120 size = sblock.fs_cssize - i < sblock.fs_bsize ? 121 sblock.fs_cssize - i : sblock.fs_bsize; 122 sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size); 123 if (bread(&dfile, (char *)sblock.fs_csp[j], 124 fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 125 size) != 0) 126 return (0); 127 } 128 /* 129 * allocate and initialize the necessary maps 130 */ 131 bmapsz = roundup(howmany(fmax, NBBY), sizeof(short)); 132 blockmap = calloc((unsigned)bmapsz, sizeof (char)); 133 if (blockmap == NULL) { 134 printf("cannot alloc %d bytes for blockmap\n", bmapsz); 135 goto badsb; 136 } 137 statemap = calloc((unsigned)(imax + 1), sizeof(char)); 138 if (statemap == NULL) { 139 printf("cannot alloc %d bytes for statemap\n", imax + 1); 140 goto badsb; 141 } 142 lncntp = (short *)calloc((unsigned)(imax + 1), sizeof(short)); 143 if (lncntp == NULL) { 144 printf("cannot alloc %d bytes for lncntp\n", 145 (imax + 1) * sizeof(short)); 146 goto badsb; 147 } 148 149 return (1); 150 151 badsb: 152 ckfini(); 153 return (0); 154 # undef altsblock 155 } 156 157 badsb(s) 158 char *s; 159 { 160 161 if (preen) 162 printf("%s: ", devname); 163 printf("BAD SUPER BLOCK: %s\n", s); 164 pwarn("USE -b OPTION TO FSCK TO SPECIFY LOCATION OF AN ALTERNATE\n"); 165 pfatal("SUPER-BLOCK TO SUPPLY NEEDED INFORMATION; SEE fsck(8).\n"); 166 } 167