xref: /csrg-svn/sbin/icheck/icheck.c (revision 6490)
1*6490Smckusick static	char *sccsid = "@(#)icheck.c	2.1 (Berkeley) 04/08/82";
24410Smckusic 
34240Smckusick /*
44240Smckusick  * icheck
54240Smckusick  */
64240Smckusick #define	NB	500
74240Smckusick #define	MAXFN	500
85349Smckusic #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
94240Smckusick 
104240Smckusick #ifndef STANDALONE
114240Smckusick #include <stdio.h>
124240Smckusick #endif
13*6490Smckusick #ifndef SIMFS
14*6490Smckusick #include <sys/param.h>
15*6490Smckusick #include <sys/inode.h>
16*6490Smckusick #include <sys/fs.h>
17*6490Smckusick #else
184240Smckusick #include "../h/param.h"
194240Smckusick #include "../h/inode.h"
204240Smckusick #include "../h/fs.h"
21*6490Smckusick #endif
224240Smckusick 
234240Smckusick union {
244240Smckusick 	struct	fs sb;
255326Smckusic 	char pad[MAXBSIZE];
264240Smckusick } sbun;
274240Smckusick #define	sblock sbun.sb
284240Smckusick 
294240Smckusick union {
304240Smckusick 	struct	cg cg;
315326Smckusic 	char pad[MAXBSIZE];
324240Smckusick } cgun;
334240Smckusick #define	cgrp cgun.cg
344240Smckusick 
354240Smckusick struct	dinode	itab[MAXIPG];
364240Smckusick daddr_t	blist[NB];
374240Smckusick char	*bmap;
384240Smckusick 
394240Smckusick int	mflg;
405098Smckusic int	sflg;
414240Smckusick int	dflg;
424240Smckusick int	fi;
434240Smckusick ino_t	ino;
444240Smckusick int	cginit;
454240Smckusick 
464240Smckusick ino_t	nrfile;
474240Smckusick ino_t	ndfile;
484240Smckusick ino_t	nbfile;
494240Smckusick ino_t	ncfile;
506286Smckusick ino_t	nlfile;
514240Smckusick 
524240Smckusick daddr_t	nblock;
534240Smckusick daddr_t	nfrag;
544240Smckusick daddr_t	nindir;
554240Smckusick daddr_t	niindir;
564240Smckusick 
574240Smckusick daddr_t	nffree;
584240Smckusick daddr_t	nbfree;
594240Smckusick 
604240Smckusick daddr_t	ndup;
614240Smckusick 
624240Smckusick int	nerror;
634240Smckusick 
645098Smckusic extern int inside[], around[];
655326Smckusic extern unsigned char *fragtbl[];
665098Smckusic 
674240Smckusick long	atol();
684240Smckusick #ifndef STANDALONE
694240Smckusick char	*malloc();
705098Smckusic char	*calloc();
714240Smckusick #endif
724240Smckusick 
734240Smckusick main(argc, argv)
745098Smckusic 	int argc;
755098Smckusic 	char *argv[];
764240Smckusick {
774240Smckusick 	register i;
784240Smckusick 	long n;
794240Smckusick 
804240Smckusick 	blist[0] = -1;
814240Smckusick #ifndef STANDALONE
824240Smckusick 	while (--argc) {
834240Smckusick 		argv++;
844240Smckusick 		if (**argv=='-')
854240Smckusick 		switch ((*argv)[1]) {
864240Smckusick 		case 'd':
874240Smckusick 			dflg++;
884240Smckusick 			continue;
894240Smckusick 
904240Smckusick 		case 'm':
914240Smckusick 			mflg++;
924240Smckusick 			continue;
934240Smckusick 
945098Smckusic 		case 's':
955098Smckusic 			sflg++;
965098Smckusic 			continue;
975098Smckusic 
984240Smckusick 		case 'b':
994240Smckusick 			for(i=0; i<NB; i++) {
1004240Smckusick 				n = atol(argv[1]);
1014240Smckusick 				if(n == 0)
1024240Smckusick 					break;
1034240Smckusick 				blist[i] = n;
1044240Smckusick 				argv++;
1054240Smckusick 				argc--;
1064240Smckusick 			}
1074240Smckusick 			blist[i] = -1;
1084240Smckusick 			continue;
1094240Smckusick 
1104240Smckusick 		default:
1114240Smckusick 			printf("Bad flag\n");
1124240Smckusick 		}
1134240Smckusick 		check(*argv);
1144240Smckusick 	}
1154240Smckusick #else
1164240Smckusick 	{
1174240Smckusick 		static char fname[128];
1184240Smckusick 
1194240Smckusick 		printf("File: ");
1204240Smckusick 		gets(fname);
1214240Smckusick 		check(fname);
1224240Smckusick 	}
1234240Smckusick #endif
1244240Smckusick 	return(nerror);
1254240Smckusick }
1264240Smckusick 
1274240Smckusick check(file)
1285098Smckusic 	char *file;
1294240Smckusick {
1304240Smckusick 	register i, j, c;
1314240Smckusick 	daddr_t d, cgd, cbase, b;
1324240Smckusick 	long n;
1334240Smckusick 
1345098Smckusic 	fi = open(file, sflg ? 2 : 0);
1354240Smckusick 	if (fi < 0) {
1365098Smckusic 		perror(file);
1374240Smckusick 		nerror |= 04;
1384240Smckusick 		return;
1394240Smckusick 	}
1404240Smckusick 	printf("%s:\n", file);
1414240Smckusick 	nrfile = 0;
1424240Smckusick 	ndfile = 0;
1434240Smckusick 	ncfile = 0;
1444240Smckusick 	nbfile = 0;
1456286Smckusick 	nlfile = 0;
1464240Smckusick 
1474240Smckusick 	nblock = 0;
1484240Smckusick 	nfrag = 0;
1494240Smckusick 	nindir = 0;
1504240Smckusick 	niindir = 0;
1514240Smckusick 
1524240Smckusick 	ndup = 0;
1534240Smckusick #ifndef STANDALONE
1544240Smckusick 	sync();
1554240Smckusick #endif
1565326Smckusic 	getsb(&sblock, file);
1575326Smckusic 	if (nerror)
1584240Smckusick 		return;
1594240Smckusick 	ino = 0;
1605098Smckusic 	n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
1614240Smckusick #ifdef STANDALONE
1624240Smckusick 	bmap = NULL;
1634240Smckusick #else
1644240Smckusick 	bmap = malloc((unsigned)n);
1654240Smckusick #endif
1664240Smckusick 	if (bmap==NULL) {
1674240Smckusick 		printf("Not enough core; duplicates unchecked\n");
1684240Smckusick 		dflg++;
1695098Smckusic 		if (sflg) {
1705098Smckusic 			printf("No Updates\n");
1715098Smckusic 			sflg = 0;
1725098Smckusic 		}
1734240Smckusick 	}
1744240Smckusick 	ino = 0;
1754240Smckusick 	cginit = 1;
1764240Smckusick 	if(!dflg) {
1774240Smckusick 		for (i=0; i<(unsigned)n; i++)
1784240Smckusick 			bmap[i] = 0;
1794240Smckusick 		for (c=0; c < sblock.fs_ncg; c++) {
1805382Smckusic 			cgd = cgtod(&sblock, c);
1815382Smckusic 			for (d = cgbase(&sblock, c); d < cgd; d += sblock.fs_frag)
1825326Smckusic 				chk(d, "badcg", sblock.fs_bsize);
1835382Smckusic 			d = cgimin(&sblock, c);
1844240Smckusick 			while (cgd < d) {
1855326Smckusic 				chk(cgd, "cg", sblock.fs_bsize);
1865326Smckusic 				cgd += sblock.fs_frag;
1874240Smckusick 			}
1885382Smckusic 			d = cgdmin(&sblock, c);
1895326Smckusic 			for (; cgd < d; cgd += sblock.fs_frag)
1905326Smckusic 				chk(cgd, "inode", sblock.fs_bsize);
1914240Smckusick 			if (c == 0) {
1925326Smckusic 				d += howmany(sblock.fs_cssize, sblock.fs_bsize)
1935326Smckusic 				    * sblock.fs_frag;
1945326Smckusic 				for (; cgd < d; cgd += sblock.fs_frag)
1955326Smckusic 					chk(cgd, "csum", sblock.fs_bsize);
1964240Smckusick 			}
1974240Smckusick 		}
1984240Smckusick 	}
1994240Smckusick 	cginit = 0;
2004240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2015382Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
2024240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
2034240Smckusick 		for (j=0; j < sblock.fs_ipg; j++) {
2044240Smckusick 			pass1(&itab[j]);
2054240Smckusick 			ino++;
2064240Smckusick 		}
2074240Smckusick 	}
2084240Smckusick 	ino = 0;
2094240Smckusick #ifndef STANDALONE
2104240Smckusick 	sync();
2114240Smckusick #endif
2125098Smckusic 	if (sflg) {
2135098Smckusic 		makecg();
2145098Smckusic 		close(fi);
2155098Smckusic #ifndef STANDALONE
2165098Smckusic 		if (bmap)
2175098Smckusic 			free(bmap);
2185098Smckusic #endif
2195098Smckusic 		return;
2205098Smckusic 	}
2214240Smckusick 	nffree = 0;
2224240Smckusick 	nbfree = 0;
2234240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2245382Smckusic 		cbase = cgbase(&sblock, c);
2255382Smckusic 		bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
2265326Smckusic 			sblock.fs_cgsize);
2275326Smckusic 		for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
2285326Smckusic 			if (isblock(&sblock, cgrp.cg_free,
2295326Smckusic 			    b / sblock.fs_frag)) {
2304240Smckusick 				nbfree++;
2315326Smckusic 				chk(cbase+b, "block", sblock.fs_bsize);
2324240Smckusick 			} else {
2335326Smckusic 				for (d = 0; d < sblock.fs_frag; d++)
2344240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
2355326Smckusic 						chk(cbase+b+d, "frag", sblock.fs_fsize);
2364240Smckusick 						nffree++;
2374240Smckusick 					}
2384240Smckusick 			}
2394240Smckusick 		}
2404240Smckusick 	}
2414240Smckusick 	close(fi);
2424240Smckusick #ifndef STANDALONE
2434240Smckusick 	if (bmap)
2444240Smckusick 		free(bmap);
2454240Smckusick #endif
2464240Smckusick 
2476286Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nlfile;
2484240Smckusick #ifndef STANDALONE
2496286Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
2506286Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
2514240Smckusick #else
2526286Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
2536286Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
2544240Smckusick #endif
2555326Smckusic 	n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
2564240Smckusick #ifdef STANDALONE
2574240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2584240Smckusick 		n, nindir, niindir, nblock, nfrag);
2595326Smckusic 	printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
2604240Smckusick 	    nbfree, nffree);
2614240Smckusick #else
2624240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2634240Smckusick 		n, nindir, niindir, nblock, nfrag);
2645326Smckusic 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
2654240Smckusick 	    nbfree, nffree);
2664240Smckusick #endif
2674240Smckusick 	if(!dflg) {
2684240Smckusick 		n = 0;
2694410Smckusic 		for (d = 0; d < sblock.fs_size; d++)
2705326Smckusic 			if(!duped(d, sblock.fs_fsize)) {
2714240Smckusick 				if(mflg)
2724240Smckusick 					printf("%ld missing\n", d);
2734240Smckusick 				n++;
2744240Smckusick 			}
2754240Smckusick 		printf("missing%5ld\n", n);
2764240Smckusick 	}
2774240Smckusick }
2784240Smckusick 
2794240Smckusick pass1(ip)
2804410Smckusic 	register struct dinode *ip;
2814240Smckusick {
2825326Smckusic 	daddr_t ind1[MAXNINDIR];
2835326Smckusic 	daddr_t ind2[MAXNINDIR];
2844429Smckusic 	daddr_t db, ib;
2854429Smckusic 	register int i, j, k, siz;
2864240Smckusick 
2874240Smckusick 	i = ip->di_mode & IFMT;
2884790Smckusic 	if(i == 0)
2894240Smckusick 		return;
2904240Smckusick 	switch (i) {
2914240Smckusick 	case IFCHR:
2924240Smckusick 		ncfile++;
2934240Smckusick 		return;
2944240Smckusick 	case IFBLK:
2954240Smckusick 		nbfile++;
2964240Smckusick 		return;
2974240Smckusick 	case IFDIR:
2984240Smckusick 		ndfile++;
2994240Smckusick 		break;
3004240Smckusick 	case IFREG:
3014240Smckusick 		nrfile++;
3024240Smckusick 		break;
3036286Smckusick 	case IFLNK:
3046286Smckusick 		nlfile++;
3056286Smckusick 		break;
3064240Smckusick 	default:
3074240Smckusick 		printf("bad mode %u\n", ino);
3084240Smckusick 		return;
3094240Smckusick 	}
3104410Smckusic 	for (i = 0; i < NDADDR; i++) {
3114410Smckusic 		db = ip->di_db[i];
3124410Smckusic 		if (db == 0)
3134240Smckusick 			continue;
3145326Smckusic 		siz = dblksize(&sblock, ip, i);
3154429Smckusic 		chk(db, "data (block)", siz);
3165326Smckusic 		if (siz == sblock.fs_bsize)
3174429Smckusic 			nblock++;
3184429Smckusic 		else
3195326Smckusic 			nfrag += howmany(siz, sblock.fs_fsize);
3204240Smckusick 	}
3214410Smckusic 	for(i = 0; i < NIADDR; i++) {
3224410Smckusic 		ib = ip->di_ib[i];
3234410Smckusic 		if(ib == 0)
3244240Smckusick 			continue;
3255326Smckusic 		if (chk(ib, "1st indirect", sblock.fs_bsize))
3264410Smckusic 			continue;
3275326Smckusic 		bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
3284240Smckusick 		nindir++;
3295326Smckusic 		for (j = 0; j < NINDIR(&sblock); j++) {
3304410Smckusic 			ib = ind1[j];
3314410Smckusic 			if (ib == 0)
3324240Smckusick 				continue;
3334410Smckusic 			if (i == 0) {
3345326Smckusic 				siz = dblksize(&sblock, ip, NDADDR + j);
3354429Smckusic 				chk(ib, "data (large)", siz);
3365326Smckusic 				if (siz == sblock.fs_bsize)
3374429Smckusic 					nblock++;
3384429Smckusic 				else
3395326Smckusic 					nfrag += howmany(siz, sblock.fs_fsize);
3404240Smckusick 				continue;
3414240Smckusick 			}
3425326Smckusic 			if (chk(ib, "2nd indirect", sblock.fs_bsize))
3434410Smckusic 				continue;
3445326Smckusic 			bread(fsbtodb(&sblock, ib), (char *)ind2,
3455326Smckusic 				sblock.fs_bsize);
3464240Smckusick 			niindir++;
3475326Smckusic 			for (k = 0; k < NINDIR(&sblock); k++) {
3484410Smckusic 				ib = ind2[k];
3494410Smckusic 				if (ib == 0)
3504240Smckusick 					continue;
3515326Smckusic 				siz = dblksize(&sblock, ip,
3525326Smckusic 				    NDADDR + NINDIR(&sblock) * (i + j) + k);
3534429Smckusic 				chk(ib, "data (huge)", siz);
3545326Smckusic 				if (siz == sblock.fs_bsize)
3554429Smckusic 					nblock++;
3564429Smckusic 				else
3575326Smckusic 					nfrag += howmany(siz, sblock.fs_fsize);
3584240Smckusick 			}
3594240Smckusick 		}
3604240Smckusick 	}
3614240Smckusick }
3624240Smckusick 
3634429Smckusic chk(bno, s, size)
3644410Smckusic 	daddr_t bno;
3654410Smckusic 	char *s;
3664429Smckusic 	int size;
3674240Smckusick {
3684240Smckusick 	register n, cg;
3695957Smckusic 	int frags;
3704240Smckusick 
3715382Smckusic 	cg = dtog(&sblock, bno);
3724429Smckusic 	if (cginit==0 &&
3735382Smckusic 	    bno<cgdmin(&sblock, cg) || bno >= sblock.fs_frag * sblock.fs_size) {
3744240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
3754240Smckusick 		return(1);
3764240Smckusick 	}
3775326Smckusic 	if (size == sblock.fs_bsize) {
3784429Smckusic 		if (duped(bno, size)) {
3794429Smckusic 			printf("%ld dup block; inode=%u, class=%s\n",
3804429Smckusic 			    bno, ino, s);
3815326Smckusic 			ndup += sblock.fs_frag;
3824429Smckusic 		}
3834429Smckusic 	} else {
3845957Smckusic 		frags = numfrags(&sblock, size);
3855957Smckusic 		for (n = 0; n < frags; n++) {
3865326Smckusic 			if (duped(bno + n, sblock.fs_fsize)) {
3874429Smckusic 				printf("%ld dup frag; inode=%u, class=%s\n",
3884429Smckusic 				    bno, ino, s);
3894429Smckusic 				ndup++;
3904429Smckusic 			}
3914429Smckusic 		}
3924240Smckusick 	}
3934240Smckusick 	for (n=0; blist[n] != -1; n++)
3944240Smckusick 		if (bno == blist[n])
3954240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
3964240Smckusick 	return(0);
3974240Smckusick }
3984240Smckusick 
3994429Smckusic duped(bno, size)
4004410Smckusic 	daddr_t bno;
4014429Smckusic 	int size;
4024240Smckusick {
4034240Smckusick 	if(dflg)
4044240Smckusick 		return(0);
4055326Smckusic 	if (size != sblock.fs_fsize && size != sblock.fs_bsize)
4064429Smckusic 		printf("bad size %d to duped\n", size);
4075326Smckusic 	if (size == sblock.fs_fsize) {
4084410Smckusic 		if (isset(bmap, bno))
4094410Smckusic 			return(1);
4104410Smckusic 		setbit(bmap, bno);
4114410Smckusic 		return (0);
4124410Smckusic 	}
4135326Smckusic 	if (bno % sblock.fs_frag != 0)
4144410Smckusic 		printf("bad bno %d to duped\n", bno);
4155326Smckusic 	if (isblock(&sblock, bmap, bno/sblock.fs_frag))
4164410Smckusic 		return (1);
4175326Smckusic 	setblock(&sblock, bmap, bno/sblock.fs_frag);
4184240Smckusick 	return(0);
4194240Smckusick }
4204240Smckusick 
4215098Smckusic makecg()
4225098Smckusic {
4235098Smckusic 	int c, blk;
4245098Smckusic 	daddr_t dbase, d, dmin, dmax;
4255098Smckusic 	long i, j, s;
4265098Smckusic 	register struct csum *cs;
4275098Smckusic 	register struct dinode *dp;
4285098Smckusic 
4295098Smckusic 	sblock.fs_cstotal.cs_nbfree = 0;
4305098Smckusic 	sblock.fs_cstotal.cs_nffree = 0;
4315098Smckusic 	sblock.fs_cstotal.cs_nifree = 0;
4325098Smckusic 	sblock.fs_cstotal.cs_ndir = 0;
4335098Smckusic 	for (c = 0; c < sblock.fs_ncg; c++) {
4345382Smckusic 		dbase = cgbase(&sblock, c);
4355098Smckusic 		dmax = dbase + sblock.fs_fpg;
4365410Smckusic 		if (dmax > sblock.fs_size) {
4375410Smckusic 			for ( ; dmax >= sblock.fs_size; dmax--)
4385400Smckusic 				clrbit(cgrp.cg_free, dmax - dbase);
4395410Smckusic 			dmax++;
4405410Smckusic 		}
4415400Smckusic 		dmin = sblock.fs_dblkno;
4425326Smckusic 		cs = &sblock.fs_cs(&sblock, c);
4435098Smckusic 		cgrp.cg_time = time(0);
4445098Smckusic 		cgrp.cg_magic = CG_MAGIC;
4455098Smckusic 		cgrp.cg_cgx = c;
4465098Smckusic 		cgrp.cg_ncyl = sblock.fs_cpg;
4475098Smckusic 		cgrp.cg_niblk = sblock.fs_ipg;
4485098Smckusic 		cgrp.cg_ndblk = dmax - dbase;
4495098Smckusic 		cgrp.cg_cs.cs_ndir = 0;
4505098Smckusic 		cgrp.cg_cs.cs_nffree = 0;
4515098Smckusic 		cgrp.cg_cs.cs_nbfree = 0;
4525098Smckusic 		cgrp.cg_cs.cs_nifree = 0;
4535098Smckusic 		cgrp.cg_rotor = dmin;
4545098Smckusic 		cgrp.cg_frotor = dmin;
4555098Smckusic 		cgrp.cg_irotor = 0;
4565326Smckusic 		for (i = 0; i < sblock.fs_frag; i++)
4575098Smckusic 			cgrp.cg_frsum[i] = 0;
4585382Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
4595098Smckusic 		      sblock.fs_ipg * sizeof(struct dinode));
4605098Smckusic 		for (i = 0; i < sblock.fs_ipg; i++) {
4615945Smckusic 			cgrp.cg_cs.cs_nifree++;
4625945Smckusic 			clrbit(cgrp.cg_iused, i);
4635098Smckusic 			dp = &itab[i];
4645098Smckusic 			if ((dp->di_mode & IFMT) != 0) {
4655098Smckusic 				if ((dp->di_mode & IFMT) == IFDIR)
4665098Smckusic 					cgrp.cg_cs.cs_ndir++;
4675945Smckusic 				cgrp.cg_cs.cs_nifree--;
4685098Smckusic 				setbit(cgrp.cg_iused, i);
4695098Smckusic 				continue;
4705098Smckusic 			}
4715098Smckusic 		}
4725098Smckusic 		while (i < MAXIPG) {
4735098Smckusic 			clrbit(cgrp.cg_iused, i);
4745098Smckusic 			i++;
4755098Smckusic 		}
4765338Smckusic 		if (c == 0)
4775338Smckusic 			for (i = 0; i < ROOTINO; i++) {
4785338Smckusic 				setbit(cgrp.cg_iused, i);
4795338Smckusic 				cgrp.cg_cs.cs_nifree--;
4805338Smckusic 			}
4815372Smckusic 		for (s = 0; s < MAXCPG; s++) {
4825372Smckusic 			cgrp.cg_btot[s] = 0;
4835098Smckusic 			for (i = 0; i < NRPOS; i++)
4845098Smckusic 				cgrp.cg_b[s][i] = 0;
4855372Smckusic 		}
4865098Smckusic 		if (c == 0) {
4875326Smckusic 			dmin += howmany(sblock.fs_cssize, sblock.fs_bsize) *
4885326Smckusic 			    sblock.fs_frag;
4895098Smckusic 		}
4905098Smckusic 		for (d = 0; d < dmin; d++)
4915098Smckusic 			clrbit(cgrp.cg_free, d);
4925326Smckusic 		for (; (d + sblock.fs_frag) <= dmax - dbase; d += sblock.fs_frag) {
4935098Smckusic 			j = 0;
4945326Smckusic 			for (i = 0; i < sblock.fs_frag; i++) {
4955098Smckusic 				if (!isset(bmap, dbase+d+i)) {
4965098Smckusic 					setbit(cgrp.cg_free, d+i);
4975098Smckusic 					j++;
4985098Smckusic 				} else
4995098Smckusic 					clrbit(cgrp.cg_free, d+i);
5005098Smckusic 			}
5015326Smckusic 			if (j == sblock.fs_frag) {
5025098Smckusic 				cgrp.cg_cs.cs_nbfree++;
5035372Smckusic 				cgrp.cg_btot[cbtocylno(&sblock, d)]++;
5045364Smckusic 				cgrp.cg_b[cbtocylno(&sblock, d)]
5055364Smckusic 				    [cbtorpos(&sblock, d)]++;
5065098Smckusic 			} else if (j > 0) {
5075098Smckusic 				cgrp.cg_cs.cs_nffree += j;
5085098Smckusic 				blk = ((cgrp.cg_free[d / NBBY] >> (d % NBBY)) &
5095326Smckusic 				       (0xff >> (NBBY - sblock.fs_frag)));
5105326Smckusic 				fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5115098Smckusic 			}
5125098Smckusic 		}
5135098Smckusic 		for (j = d; d < dmax - dbase; d++) {
5145098Smckusic 			if (!isset(bmap, dbase+d)) {
5155098Smckusic 				setbit(cgrp.cg_free, d);
5165098Smckusic 				cgrp.cg_cs.cs_nffree++;
5175098Smckusic 			} else
5185098Smckusic 				clrbit(cgrp.cg_free, d);
5195098Smckusic 		}
5205098Smckusic 		if (j != d) {
5215098Smckusic 			blk = ((cgrp.cg_free[j / NBBY] >> (j % NBBY)) &
5225326Smckusic 			       (0xff >> (NBBY - sblock.fs_frag)));
5235326Smckusic 			fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5245098Smckusic 		}
5255326Smckusic 		for (; d < MAXBPG(&sblock); d++)
5265098Smckusic 			clrbit(cgrp.cg_free, d);
5275098Smckusic 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
5285098Smckusic 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
5295098Smckusic 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
5305098Smckusic 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
5315098Smckusic 		*cs = cgrp.cg_cs;
5325382Smckusic 		bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp,
5335326Smckusic 			sblock.fs_cgsize);
5345098Smckusic 	}
5355326Smckusic 	for (i = 0; i < howmany(sblock.fs_cssize, sblock.fs_bsize); i++) {
5365326Smckusic 		bwrite(fsbtodb(&sblock,
5375326Smckusic 		    sblock.fs_csaddr + (i * sblock.fs_frag)),
5385326Smckusic 		    (char *)sblock.fs_csp[i], sblock.fs_bsize);
5395098Smckusic 	}
5405098Smckusic 	sblock.fs_ronly = 0;
5415098Smckusic 	sblock.fs_fmod = 0;
5425349Smckusic 	bwrite(SBLOCK, (char *)&sblock, SBSIZE);
5435098Smckusic }
5445098Smckusic 
5455098Smckusic /*
5465098Smckusic  * update the frsum fields to reflect addition or deletion
5475098Smckusic  * of some frags
5485098Smckusic  */
5495326Smckusic fragacct(fs, fragmap, fraglist, cnt)
5505326Smckusic 	struct fs *fs;
5515098Smckusic 	int fragmap;
5525098Smckusic 	long fraglist[];
5535098Smckusic 	int cnt;
5545098Smckusic {
5555098Smckusic 	int inblk;
5565098Smckusic 	register int field, subfield;
5575098Smckusic 	register int siz, pos;
5585098Smckusic 
5595326Smckusic 	inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
5605098Smckusic 	fragmap <<= 1;
5615326Smckusic 	for (siz = 1; siz < fs->fs_frag; siz++) {
5626291Smckusick 		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
5635098Smckusic 			continue;
5645098Smckusic 		field = around[siz];
5655098Smckusic 		subfield = inside[siz];
5665326Smckusic 		for (pos = siz; pos <= fs->fs_frag; pos++) {
5675098Smckusic 			if ((fragmap & field) == subfield) {
5685098Smckusic 				fraglist[siz] += cnt;
5695098Smckusic 				pos += siz;
5705098Smckusic 				field <<= siz;
5715098Smckusic 				subfield <<= siz;
5725098Smckusic 			}
5735098Smckusic 			field <<= 1;
5745098Smckusic 			subfield <<= 1;
5755098Smckusic 		}
5765098Smckusic 	}
5775098Smckusic }
5785098Smckusic 
5795326Smckusic getsb(fs, file)
5805326Smckusic 	register struct fs *fs;
5815326Smckusic 	char *file;
5825326Smckusic {
5835326Smckusic 	int i;
5845326Smckusic 
5855349Smckusic 	if (bread(SBLOCK, fs, SBSIZE)) {
5865326Smckusic 		printf("bad super block");
5875326Smckusic 		perror(file);
5885326Smckusic 		nerror |= 04;
5895326Smckusic 		return;
5905326Smckusic 	}
5915326Smckusic 	if (fs->fs_magic != FS_MAGIC) {
5925326Smckusic 		printf("%s: bad magic number\n", file);
5935326Smckusic 		nerror |= 04;
5945326Smckusic 		return;
5955326Smckusic 	}
5965326Smckusic 	for (i = 0; i < howmany(fs->fs_cssize, fs->fs_bsize); i++) {
5975326Smckusic 		fs->fs_csp[i] = (struct csum *)calloc(1, fs->fs_bsize);
5985326Smckusic 		bread(fsbtodb(fs, fs->fs_csaddr + (i * fs->fs_frag)),
5995326Smckusic 		      (char *)fs->fs_csp[i], fs->fs_bsize);
6005326Smckusic 	}
6015326Smckusic }
6025326Smckusic 
6035098Smckusic bwrite(blk, buf, size)
6045098Smckusic 	char *buf;
6055098Smckusic 	daddr_t blk;
6065098Smckusic 	register size;
6075098Smckusic {
6085326Smckusic 	if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
6095098Smckusic 		perror("FS SEEK");
6105098Smckusic 		return(1);
6115098Smckusic 	}
6125098Smckusic 	if (write(fi, buf, size) != size) {
6135098Smckusic 		perror("FS WRITE");
6145098Smckusic 		return(1);
6155098Smckusic 	}
6165326Smckusic 	return (0);
6175098Smckusic }
6185098Smckusic 
6194240Smckusick bread(bno, buf, cnt)
6204410Smckusic 	daddr_t bno;
6214410Smckusic 	char *buf;
6224240Smckusick {
6234240Smckusick 	register i;
6244240Smckusick 
6255326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
6264240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
6275098Smckusic 		if (sflg) {
6285098Smckusic 			printf("No Update\n");
6295098Smckusic 			sflg = 0;
6305098Smckusic 		}
6315326Smckusic 		for(i=0; i<sblock.fs_bsize; i++)
6324240Smckusick 			buf[i] = 0;
6335326Smckusic 		return (1);
6344240Smckusick 	}
6355326Smckusic 	return (0);
6364240Smckusick }
6375326Smckusic 
6385326Smckusic /*
6395326Smckusic  * block operations
6405326Smckusic  */
6415326Smckusic 
6425326Smckusic isblock(fs, cp, h)
6435326Smckusic 	struct fs *fs;
6445326Smckusic 	unsigned char *cp;
6455326Smckusic 	int h;
6465326Smckusic {
6475326Smckusic 	unsigned char mask;
6485326Smckusic 
6495326Smckusic 	switch (fs->fs_frag) {
6505326Smckusic 	case 8:
6515326Smckusic 		return (cp[h] == 0xff);
6525326Smckusic 	case 4:
6535326Smckusic 		mask = 0x0f << ((h & 0x1) << 2);
6545326Smckusic 		return ((cp[h >> 1] & mask) == mask);
6555326Smckusic 	case 2:
6565326Smckusic 		mask = 0x03 << ((h & 0x3) << 1);
6575326Smckusic 		return ((cp[h >> 2] & mask) == mask);
6585326Smckusic 	case 1:
6595326Smckusic 		mask = 0x01 << (h & 0x7);
6605326Smckusic 		return ((cp[h >> 3] & mask) == mask);
6615326Smckusic 	default:
6625326Smckusic 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
6635326Smckusic 		return;
6645326Smckusic 	}
6655326Smckusic }
6665326Smckusic 
6675326Smckusic setblock(fs, cp, h)
6685326Smckusic 	struct fs *fs;
6695326Smckusic 	unsigned char *cp;
6705326Smckusic 	int h;
6715326Smckusic {
6725326Smckusic 	switch (fs->fs_frag) {
6735326Smckusic 	case 8:
6745326Smckusic 		cp[h] = 0xff;
6755326Smckusic 		return;
6765326Smckusic 	case 4:
6775326Smckusic 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
6785326Smckusic 		return;
6795326Smckusic 	case 2:
6805326Smckusic 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
6815326Smckusic 		return;
6825326Smckusic 	case 1:
6835326Smckusic 		cp[h >> 3] |= (0x01 << (h & 0x7));
6845326Smckusic 		return;
6855326Smckusic 	default:
6865326Smckusic 		fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
6875326Smckusic 		return;
6885326Smckusic 	}
6895326Smckusic }
690*6490Smckusick 
691*6490Smckusick /*	tables.c	4.1	82/03/25	*/
692*6490Smckusick 
693*6490Smckusick /* merged into kernel:	tables.c 2.1 3/25/82 */
694*6490Smckusick 
695*6490Smckusick /* last monet version:	partab.c	4.2	81/03/08	*/
696*6490Smckusick 
697*6490Smckusick /*
698*6490Smckusick  * bit patterns for identifying fragments in the block map
699*6490Smckusick  * used as ((map & around) == inside)
700*6490Smckusick  */
701*6490Smckusick int around[9] = {
702*6490Smckusick 	0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
703*6490Smckusick };
704*6490Smckusick int inside[9] = {
705*6490Smckusick 	0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
706*6490Smckusick };
707*6490Smckusick 
708*6490Smckusick /*
709*6490Smckusick  * given a block map bit pattern, the frag tables tell whether a
710*6490Smckusick  * particular size fragment is available.
711*6490Smckusick  *
712*6490Smckusick  * used as:
713*6490Smckusick  * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] {
714*6490Smckusick  *	at least one fragment of the indicated size is available
715*6490Smckusick  * }
716*6490Smckusick  *
717*6490Smckusick  * These tables are used by the scanc instruction on the VAX to
718*6490Smckusick  * quickly find an appropriate fragment.
719*6490Smckusick  */
720*6490Smckusick 
721*6490Smckusick unsigned char fragtbl124[256] = {
722*6490Smckusick 	0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
723*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
724*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
725*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
726*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
727*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
728*6490Smckusick 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
729*6490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
730*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
731*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
732*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
733*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
734*6490Smckusick 	0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e,
735*6490Smckusick 	0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae,
736*6490Smckusick 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
737*6490Smckusick 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
738*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
739*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
740*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
741*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
742*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
743*6490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
744*6490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
745*6490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
746*6490Smckusick 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
747*6490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
748*6490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
749*6490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
750*6490Smckusick 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
751*6490Smckusick 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
752*6490Smckusick 	0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce,
753*6490Smckusick 	0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
754*6490Smckusick };
755*6490Smckusick 
756*6490Smckusick unsigned char fragtbl8[256] = {
757*6490Smckusick 	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
758*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
759*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
760*6490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
761*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
762*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
763*6490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
764*6490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
765*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
766*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
767*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
768*6490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
769*6490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
770*6490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
771*6490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
772*6490Smckusick 	0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40,
773*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
774*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
775*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
776*6490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
777*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
778*6490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
779*6490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
780*6490Smckusick 	0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
781*6490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
782*6490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
783*6490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
784*6490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12,
785*6490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
786*6490Smckusick 	0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c,
787*6490Smckusick 	0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c,
788*6490Smckusick 	0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
789*6490Smckusick };
790*6490Smckusick 
791*6490Smckusick /*
792*6490Smckusick  * the actual fragtbl array
793*6490Smckusick  */
794*6490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = {
795*6490Smckusick 	0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
796*6490Smckusick };
797