xref: /csrg-svn/sbin/fsck/setup.c (revision 17931)
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