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