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