xref: /csrg-svn/sbin/icheck/icheck.c (revision 30558)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 static char sccsid[] = "@(#)icheck.c	5.2 (Berkeley) 02/23/87";
9 #endif not lint
10 
11 
12 /*
13  * icheck
14  */
15 #define	NB	500
16 #define	MAXFN	500
17 #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
18 
19 #ifndef STANDALONE
20 #include <stdio.h>
21 #endif
22 #ifndef SIMFS
23 #include <sys/param.h>
24 #include <sys/inode.h>
25 #include <sys/fs.h>
26 #else
27 #include "../h/param.h"
28 #include "../h/inode.h"
29 #include "../h/fs.h"
30 #endif
31 
32 union {
33 	struct	fs sb;
34 	char pad[MAXBSIZE];
35 } sbun;
36 #define	sblock sbun.sb
37 
38 union {
39 	struct	cg cg;
40 	char pad[MAXBSIZE];
41 } cgun;
42 #define	cgrp cgun.cg
43 
44 struct	dinode	itab[MAXIPG];
45 daddr_t	blist[NB];
46 daddr_t	fsblist[NB];
47 char	*bmap;
48 
49 int	mflg;
50 int	sflg;
51 int	dflg;
52 int	fi;
53 ino_t	ino;
54 int	cginit;
55 
56 ino_t	nrfile;
57 ino_t	ndfile;
58 ino_t	nbfile;
59 ino_t	ncfile;
60 ino_t	nlfile;
61 
62 daddr_t	nblock;
63 daddr_t	nfrag;
64 daddr_t	nindir;
65 daddr_t	niindir;
66 
67 daddr_t	nffree;
68 daddr_t	nbfree;
69 
70 daddr_t	ndup;
71 
72 int	nerror;
73 long	dev_bsize = 1;
74 
75 extern int inside[], around[];
76 extern unsigned char *fragtbl[];
77 
78 long	atol();
79 #ifndef STANDALONE
80 char	*malloc();
81 char	*calloc();
82 #endif
83 
84 main(argc, argv)
85 	int argc;
86 	char *argv[];
87 {
88 	register i;
89 	long n;
90 
91 	blist[0] = -1;
92 #ifndef STANDALONE
93 	while (--argc) {
94 		argv++;
95 		if (**argv=='-')
96 		switch ((*argv)[1]) {
97 		case 'd':
98 			dflg++;
99 			continue;
100 
101 		case 'm':
102 			mflg++;
103 			continue;
104 
105 		case 's':
106 			sflg++;
107 			continue;
108 
109 		case 'b':
110 			for(i=0; i<NB; i++) {
111 				n = atol(argv[1]);
112 				if(n == 0)
113 					break;
114 				blist[i] = n;
115 				argv++;
116 				argc--;
117 			}
118 			blist[i] = -1;
119 			continue;
120 
121 		default:
122 			printf("Bad flag\n");
123 		}
124 		check(*argv);
125 	}
126 #else
127 	{
128 		static char fname[128];
129 
130 		printf("File: ");
131 		gets(fname);
132 		check(fname);
133 	}
134 #endif
135 	return(nerror);
136 }
137 
138 check(file)
139 	char *file;
140 {
141 	register i, j, c;
142 	daddr_t d, cgd, cbase, b;
143 	long n;
144 	char buf[BUFSIZ];
145 
146 	fi = open(file, sflg ? 2 : 0);
147 	if (fi < 0) {
148 		perror(file);
149 		nerror |= 04;
150 		return;
151 	}
152 	printf("%s:\n", file);
153 	nrfile = 0;
154 	ndfile = 0;
155 	ncfile = 0;
156 	nbfile = 0;
157 	nlfile = 0;
158 
159 	nblock = 0;
160 	nfrag = 0;
161 	nindir = 0;
162 	niindir = 0;
163 
164 	ndup = 0;
165 #ifndef STANDALONE
166 	sync();
167 #endif
168 	getsb(&sblock, file);
169 	if (nerror)
170 		return;
171 	for (n=0; blist[n] != -1; n++)
172 		fsblist[n] = dbtofsb(&sblock, blist[n]);
173 	ino = 0;
174 	n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
175 #ifdef STANDALONE
176 	bmap = NULL;
177 #else
178 	bmap = malloc((unsigned)n);
179 #endif
180 	if (bmap==NULL) {
181 		printf("Not enough core; duplicates unchecked\n");
182 		dflg++;
183 		if (sflg) {
184 			printf("No Updates\n");
185 			sflg = 0;
186 		}
187 	}
188 	ino = 0;
189 	cginit = 1;
190 	if (!dflg) {
191 		for (i = 0; i < (unsigned)n; i++)
192 			bmap[i] = 0;
193 		for (c = 0; c < sblock.fs_ncg; c++) {
194 			cgd = cgtod(&sblock, c);
195 			if (c == 0)
196 				d = cgbase(&sblock, c);
197 			else
198 				d = cgsblock(&sblock, c);
199 			sprintf(buf, "spare super block %d", c);
200 			for (; d < cgd; d += sblock.fs_frag)
201 				chk(d, buf, sblock.fs_bsize);
202 			d = cgimin(&sblock, c);
203 			sprintf(buf, "cylinder group %d", c);
204 			while (cgd < d) {
205 				chk(cgd, buf, sblock.fs_bsize);
206 				cgd += sblock.fs_frag;
207 			}
208 			d = cgdmin(&sblock, c);
209 			i = INOPB(&sblock);
210 			for (; cgd < d; cgd += sblock.fs_frag) {
211 				sprintf(buf, "inodes %d-%d", ino, ino + i);
212 				chk(cgd, buf, sblock.fs_bsize);
213 				ino += i;
214 			}
215 			if (c == 0) {
216 				d += howmany(sblock.fs_cssize, sblock.fs_fsize);
217 				for (; cgd < d; cgd++)
218 					chk(cgd, "csum", sblock.fs_fsize);
219 			}
220 		}
221 	}
222 	ino = 0;
223 	cginit = 0;
224 	for (c = 0; c < sblock.fs_ncg; c++) {
225 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
226 		    sblock.fs_ipg * sizeof (struct dinode));
227 		for (j=0; j < sblock.fs_ipg; j++) {
228 			pass1(&itab[j]);
229 			ino++;
230 		}
231 	}
232 	ino = 0;
233 #ifndef STANDALONE
234 	sync();
235 #endif
236 	if (sflg) {
237 		makecg();
238 		close(fi);
239 #ifndef STANDALONE
240 		if (bmap)
241 			free(bmap);
242 #endif
243 		return;
244 	}
245 	nffree = 0;
246 	nbfree = 0;
247 	for (c = 0; c < sblock.fs_ncg; c++) {
248 		cbase = cgbase(&sblock, c);
249 		bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
250 			sblock.fs_cgsize);
251 		if (cgrp.cg_magic != CG_MAGIC)
252 			printf("cg %d: bad magic number\n", c);
253 		for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
254 			if (isblock(&sblock, cgrp.cg_free,
255 			    b / sblock.fs_frag)) {
256 				nbfree++;
257 				chk(cbase+b, "free block", sblock.fs_bsize);
258 			} else {
259 				for (d = 0; d < sblock.fs_frag; d++)
260 					if (isset(cgrp.cg_free, b+d)) {
261 						chk(cbase+b+d, "free frag", sblock.fs_fsize);
262 						nffree++;
263 					}
264 			}
265 		}
266 	}
267 	close(fi);
268 #ifndef STANDALONE
269 	if (bmap)
270 		free(bmap);
271 #endif
272 
273 	i = nrfile + ndfile + ncfile + nbfile + nlfile;
274 #ifndef STANDALONE
275 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
276 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
277 #else
278 	printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
279 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
280 #endif
281 	n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
282 #ifdef STANDALONE
283 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
284 		n, nindir, niindir, nblock, nfrag);
285 	printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
286 	    nbfree, nffree);
287 #else
288 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
289 		n, nindir, niindir, nblock, nfrag);
290 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
291 	    nbfree, nffree);
292 #endif
293 	if(!dflg) {
294 		n = 0;
295 		for (d = 0; d < sblock.fs_size; d++)
296 			if(!duped(d, sblock.fs_fsize)) {
297 				if(mflg)
298 					printf("%ld missing\n", d);
299 				n++;
300 			}
301 		printf("missing%5ld\n", n);
302 	}
303 }
304 
305 pass1(ip)
306 	register struct dinode *ip;
307 {
308 	daddr_t ind1[MAXNINDIR];
309 	daddr_t ind2[MAXNINDIR];
310 	daddr_t db, ib;
311 	register int i, j, k, siz;
312 	int lbn;
313 	char buf[BUFSIZ];
314 
315 	i = ip->di_mode & IFMT;
316 	if(i == 0)
317 		return;
318 	switch (i) {
319 	case IFCHR:
320 		ncfile++;
321 		return;
322 	case IFBLK:
323 		nbfile++;
324 		return;
325 	case IFDIR:
326 		ndfile++;
327 		break;
328 	case IFREG:
329 		nrfile++;
330 		break;
331 	case IFLNK:
332 		nlfile++;
333 		break;
334 	default:
335 		printf("bad mode %u\n", ino);
336 		return;
337 	}
338 	for (i = 0; i < NDADDR; i++) {
339 		db = ip->di_db[i];
340 		if (db == 0)
341 			continue;
342 		siz = dblksize(&sblock, ip, i);
343 		sprintf(buf, "logical data block %d", i);
344 		chk(db, buf, siz);
345 		if (siz == sblock.fs_bsize)
346 			nblock++;
347 		else
348 			nfrag += howmany(siz, sblock.fs_fsize);
349 	}
350 	for(i = 0; i < NIADDR; i++) {
351 		ib = ip->di_ib[i];
352 		if (ib == 0)
353 			continue;
354 		if (chk(ib, "1st indirect", sblock.fs_bsize))
355 			continue;
356 		bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
357 		nindir++;
358 		for (j = 0; j < NINDIR(&sblock); j++) {
359 			ib = ind1[j];
360 			if (ib == 0)
361 				continue;
362 			if (i == 0) {
363 				lbn = NDADDR + j;
364 				siz = dblksize(&sblock, ip, lbn);
365 				sprintf(buf, "logical data block %d", lbn);
366 				chk(ib, buf, siz);
367 				if (siz == sblock.fs_bsize)
368 					nblock++;
369 				else
370 					nfrag += howmany(siz, sblock.fs_fsize);
371 				continue;
372 			}
373 			if (chk(ib, "2nd indirect", sblock.fs_bsize))
374 				continue;
375 			bread(fsbtodb(&sblock, ib), (char *)ind2,
376 				sblock.fs_bsize);
377 			niindir++;
378 			for (k = 0; k < NINDIR(&sblock); k++) {
379 				ib = ind2[k];
380 				if (ib == 0)
381 					continue;
382 				lbn = NDADDR + NINDIR(&sblock) * (i + j) + k;
383 				siz = dblksize(&sblock, ip, lbn);
384 				sprintf(buf, "logical data block %d", lbn);
385 				chk(ib, buf, siz);
386 				if (siz == sblock.fs_bsize)
387 					nblock++;
388 				else
389 					nfrag += howmany(siz, sblock.fs_fsize);
390 			}
391 		}
392 	}
393 }
394 
395 chk(bno, s, size)
396 	daddr_t bno;
397 	char *s;
398 	int size;
399 {
400 	register n, cg;
401 	int frags;
402 
403 	cg = dtog(&sblock, bno);
404 	if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) {
405 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
406 		return(1);
407 	}
408 	frags = numfrags(&sblock, size);
409 	if (frags == sblock.fs_frag) {
410 		if (duped(bno, size)) {
411 			printf("%ld dup block; inode=%u, class=%s\n",
412 			    bno, ino, s);
413 			ndup += sblock.fs_frag;
414 		}
415 	} else {
416 		for (n = 0; n < frags; n++) {
417 			if (duped(bno + n, sblock.fs_fsize)) {
418 				printf("%ld dup frag; inode=%u, class=%s\n",
419 				    bno, ino, s);
420 				ndup++;
421 			}
422 		}
423 	}
424 	for (n=0; blist[n] != -1; n++)
425 		if (fsblist[n] >= bno && fsblist[n] < bno + frags)
426 			printf("%ld arg; frag %d of %d, inode=%u, class=%s\n",
427 				blist[n], fsblist[n] - bno, frags, ino, s);
428 	return(0);
429 }
430 
431 duped(bno, size)
432 	daddr_t bno;
433 	int size;
434 {
435 	if(dflg)
436 		return(0);
437 	if (size != sblock.fs_fsize && size != sblock.fs_bsize)
438 		printf("bad size %d to duped\n", size);
439 	if (size == sblock.fs_fsize) {
440 		if (isset(bmap, bno))
441 			return(1);
442 		setbit(bmap, bno);
443 		return (0);
444 	}
445 	if (bno % sblock.fs_frag != 0)
446 		printf("bad bno %d to duped\n", bno);
447 	if (isblock(&sblock, bmap, bno/sblock.fs_frag))
448 		return (1);
449 	setblock(&sblock, bmap, bno/sblock.fs_frag);
450 	return(0);
451 }
452 
453 makecg()
454 {
455 	int c, blk;
456 	daddr_t dbase, d, dlower, dupper, dmax;
457 	long i, j, s;
458 	register struct csum *cs;
459 	register struct dinode *dp;
460 
461 	sblock.fs_cstotal.cs_nbfree = 0;
462 	sblock.fs_cstotal.cs_nffree = 0;
463 	sblock.fs_cstotal.cs_nifree = 0;
464 	sblock.fs_cstotal.cs_ndir = 0;
465 	for (c = 0; c < sblock.fs_ncg; c++) {
466 		dbase = cgbase(&sblock, c);
467 		dmax = dbase + sblock.fs_fpg;
468 		if (dmax > sblock.fs_size) {
469 			for ( ; dmax >= sblock.fs_size; dmax--)
470 				clrbit(cgrp.cg_free, dmax - dbase);
471 			dmax++;
472 		}
473 		dlower = cgsblock(&sblock, c) - dbase;
474 		dupper = cgdmin(&sblock, c) - dbase;
475 		cs = &sblock.fs_cs(&sblock, c);
476 		cgrp.cg_time = time(0);
477 		cgrp.cg_magic = CG_MAGIC;
478 		cgrp.cg_cgx = c;
479 		if (c == sblock.fs_ncg - 1)
480 			cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg;
481 		else
482 			cgrp.cg_ncyl = sblock.fs_cpg;
483 		cgrp.cg_niblk = sblock.fs_ipg;
484 		cgrp.cg_ndblk = dmax - dbase;
485 		cgrp.cg_cs.cs_ndir = 0;
486 		cgrp.cg_cs.cs_nffree = 0;
487 		cgrp.cg_cs.cs_nbfree = 0;
488 		cgrp.cg_cs.cs_nifree = 0;
489 		cgrp.cg_rotor = 0;
490 		cgrp.cg_frotor = 0;
491 		cgrp.cg_irotor = 0;
492 		for (i = 0; i < sblock.fs_frag; i++)
493 			cgrp.cg_frsum[i] = 0;
494 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
495 		      sblock.fs_ipg * sizeof(struct dinode));
496 		for (i = 0; i < sblock.fs_ipg; i++) {
497 			cgrp.cg_cs.cs_nifree++;
498 			clrbit(cgrp.cg_iused, i);
499 			dp = &itab[i];
500 			if ((dp->di_mode & IFMT) != 0) {
501 				if ((dp->di_mode & IFMT) == IFDIR)
502 					cgrp.cg_cs.cs_ndir++;
503 				cgrp.cg_cs.cs_nifree--;
504 				setbit(cgrp.cg_iused, i);
505 				continue;
506 			}
507 		}
508 		while (i < MAXIPG) {
509 			clrbit(cgrp.cg_iused, i);
510 			i++;
511 		}
512 		if (c == 0)
513 			for (i = 0; i < ROOTINO; i++) {
514 				setbit(cgrp.cg_iused, i);
515 				cgrp.cg_cs.cs_nifree--;
516 			}
517 		for (s = 0; s < MAXCPG; s++) {
518 			cgrp.cg_btot[s] = 0;
519 			for (i = 0; i < NRPOS; i++)
520 				cgrp.cg_b[s][i] = 0;
521 		}
522 		if (c == 0) {
523 			dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
524 		}
525 		for (d = dlower; d < dupper; d++)
526 			clrbit(cgrp.cg_free, d);
527 		for (d = 0; (d + sblock.fs_frag) <= dmax - dbase;
528 		    d += sblock.fs_frag) {
529 			j = 0;
530 			for (i = 0; i < sblock.fs_frag; i++) {
531 				if (!isset(bmap, dbase + d + i)) {
532 					setbit(cgrp.cg_free, d + i);
533 					j++;
534 				} else
535 					clrbit(cgrp.cg_free, d+i);
536 			}
537 			if (j == sblock.fs_frag) {
538 				cgrp.cg_cs.cs_nbfree++;
539 				cgrp.cg_btot[cbtocylno(&sblock, d)]++;
540 				cgrp.cg_b[cbtocylno(&sblock, d)]
541 				    [cbtorpos(&sblock, d)]++;
542 			} else if (j > 0) {
543 				cgrp.cg_cs.cs_nffree += j;
544 				blk = blkmap(&sblock, cgrp.cg_free, d);
545 				fragacct(&sblock, blk, cgrp.cg_frsum, 1);
546 			}
547 		}
548 		for (j = d; d < dmax - dbase; d++) {
549 			if (!isset(bmap, dbase + d)) {
550 				setbit(cgrp.cg_free, d);
551 				cgrp.cg_cs.cs_nffree++;
552 			} else
553 				clrbit(cgrp.cg_free, d);
554 		}
555 		for (; d % sblock.fs_frag != 0; d++)
556 			clrbit(cgrp.cg_free, d);
557 		if (j != d) {
558 			blk = blkmap(&sblock, cgrp.cg_free, j);
559 			fragacct(&sblock, blk, cgrp.cg_frsum, 1);
560 		}
561 		for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++)
562 			clrblock(&sblock, cgrp.cg_free, d);
563 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
564 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
565 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
566 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
567 		*cs = cgrp.cg_cs;
568 		bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp,
569 			sblock.fs_cgsize);
570 	}
571 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
572 		bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
573 		    (char *)sblock.fs_csp[j],
574 		    sblock.fs_cssize - i < sblock.fs_bsize ?
575 		    sblock.fs_cssize - i : sblock.fs_bsize);
576 	}
577 	sblock.fs_ronly = 0;
578 	sblock.fs_fmod = 0;
579 	bwrite(SBOFF / dev_bsize, (char *)&sblock, SBSIZE);
580 }
581 
582 /*
583  * update the frsum fields to reflect addition or deletion
584  * of some frags
585  */
586 fragacct(fs, fragmap, fraglist, cnt)
587 	struct fs *fs;
588 	int fragmap;
589 	long fraglist[];
590 	int cnt;
591 {
592 	int inblk;
593 	register int field, subfield;
594 	register int siz, pos;
595 
596 	inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
597 	fragmap <<= 1;
598 	for (siz = 1; siz < fs->fs_frag; siz++) {
599 		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
600 			continue;
601 		field = around[siz];
602 		subfield = inside[siz];
603 		for (pos = siz; pos <= fs->fs_frag; pos++) {
604 			if ((fragmap & field) == subfield) {
605 				fraglist[siz] += cnt;
606 				pos += siz;
607 				field <<= siz;
608 				subfield <<= siz;
609 			}
610 			field <<= 1;
611 			subfield <<= 1;
612 		}
613 	}
614 }
615 
616 getsb(fs, file)
617 	register struct fs *fs;
618 	char *file;
619 {
620 	int i, j, size;
621 
622 	if (bread(SBOFF, fs, SBSIZE)) {
623 		printf("bad super block");
624 		perror(file);
625 		nerror |= 04;
626 		return;
627 	}
628 	if (fs->fs_magic != FS_MAGIC) {
629 		printf("%s: bad magic number\n", file);
630 		nerror |= 04;
631 		return;
632 	}
633 	dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
634 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
635 		size = sblock.fs_cssize - i < sblock.fs_bsize ?
636 		    sblock.fs_cssize - i : sblock.fs_bsize;
637 		sblock.fs_csp[j] = (struct csum *)calloc(1, size);
638 		bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)),
639 		      (char *)fs->fs_csp[j], size);
640 	}
641 }
642 
643 bwrite(blk, buf, size)
644 	char *buf;
645 	daddr_t blk;
646 	register size;
647 {
648 	if (lseek(fi, blk * dev_bsize, 0) < 0) {
649 		perror("FS SEEK");
650 		return(1);
651 	}
652 	if (write(fi, buf, size) != size) {
653 		perror("FS WRITE");
654 		return(1);
655 	}
656 	return (0);
657 }
658 
659 bread(bno, buf, cnt)
660 	daddr_t bno;
661 	char *buf;
662 {
663 	register i;
664 
665 	lseek(fi, bno * dev_bsize, 0);
666 	if ((i = read(fi, buf, cnt)) != cnt) {
667 		if (sflg) {
668 			printf("No Update\n");
669 			sflg = 0;
670 		}
671 		for(i=0; i<sblock.fs_bsize; i++)
672 			buf[i] = 0;
673 		return (1);
674 	}
675 	return (0);
676 }
677 
678 /*
679  * check if a block is available
680  */
681 isblock(fs, cp, h)
682 	struct fs *fs;
683 	unsigned char *cp;
684 	int h;
685 {
686 	unsigned char mask;
687 
688 	switch (fs->fs_frag) {
689 	case 8:
690 		return (cp[h] == 0xff);
691 	case 4:
692 		mask = 0x0f << ((h & 0x1) << 2);
693 		return ((cp[h >> 1] & mask) == mask);
694 	case 2:
695 		mask = 0x03 << ((h & 0x3) << 1);
696 		return ((cp[h >> 2] & mask) == mask);
697 	case 1:
698 		mask = 0x01 << (h & 0x7);
699 		return ((cp[h >> 3] & mask) == mask);
700 	default:
701 #ifdef STANDALONE
702 		printf("isblock bad fs_frag %d\n", fs->fs_frag);
703 #else
704 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
705 #endif
706 		return;
707 	}
708 }
709 
710 /*
711  * take a block out of the map
712  */
713 clrblock(fs, cp, h)
714 	struct fs *fs;
715 	unsigned char *cp;
716 	int h;
717 {
718 	switch ((fs)->fs_frag) {
719 	case 8:
720 		cp[h] = 0;
721 		return;
722 	case 4:
723 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
724 		return;
725 	case 2:
726 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
727 		return;
728 	case 1:
729 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
730 		return;
731 	default:
732 #ifdef STANDALONE
733 		printf("clrblock bad fs_frag %d\n", fs->fs_frag);
734 #else
735 		fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
736 #endif
737 		return;
738 	}
739 }
740 
741 /*
742  * put a block into the map
743  */
744 setblock(fs, cp, h)
745 	struct fs *fs;
746 	unsigned char *cp;
747 	int h;
748 {
749 	switch (fs->fs_frag) {
750 	case 8:
751 		cp[h] = 0xff;
752 		return;
753 	case 4:
754 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
755 		return;
756 	case 2:
757 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
758 		return;
759 	case 1:
760 		cp[h >> 3] |= (0x01 << (h & 0x7));
761 		return;
762 	default:
763 #ifdef STANDALONE
764 		printf("setblock bad fs_frag %d\n", fs->fs_frag);
765 #else
766 		fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
767 #endif
768 		return;
769 	}
770 }
771 
772 /*	tables.c	4.1	82/03/25	*/
773 
774 /* merged into kernel:	tables.c 2.1 3/25/82 */
775 
776 /* last monet version:	partab.c	4.2	81/03/08	*/
777 
778 /*
779  * bit patterns for identifying fragments in the block map
780  * used as ((map & around) == inside)
781  */
782 int around[9] = {
783 	0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
784 };
785 int inside[9] = {
786 	0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
787 };
788 
789 /*
790  * given a block map bit pattern, the frag tables tell whether a
791  * particular size fragment is available.
792  *
793  * used as:
794  * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] {
795  *	at least one fragment of the indicated size is available
796  * }
797  *
798  * These tables are used by the scanc instruction on the VAX to
799  * quickly find an appropriate fragment.
800  */
801 
802 unsigned char fragtbl124[256] = {
803 	0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
804 	0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
805 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
806 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
807 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
808 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
809 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
810 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
811 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
812 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
813 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
814 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
815 	0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e,
816 	0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae,
817 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
818 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
819 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
820 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
821 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
822 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
823 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
824 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
825 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
826 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
827 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
828 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
829 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
830 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
831 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
832 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
833 	0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce,
834 	0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
835 };
836 
837 unsigned char fragtbl8[256] = {
838 	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
839 	0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
840 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
841 	0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
842 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
843 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
844 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
845 	0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
846 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
847 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
848 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
849 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
850 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
851 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
852 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
853 	0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40,
854 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
855 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
856 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
857 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
858 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
859 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
860 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
861 	0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
862 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
863 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
864 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
865 	0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12,
866 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
867 	0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c,
868 	0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c,
869 	0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
870 };
871 
872 /*
873  * the actual fragtbl array
874  */
875 unsigned char *fragtbl[MAXFRAG + 1] = {
876 	0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
877 };
878