xref: /csrg-svn/sbin/icheck/icheck.c (revision 6534)
1*6534Smckusick static	char *sccsid = "@(#)icheck.c	2.2 (Berkeley) 04/11/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
136490Smckusick #ifndef SIMFS
146490Smckusick #include <sys/param.h>
156490Smckusick #include <sys/inode.h>
166490Smckusick #include <sys/fs.h>
176490Smckusick #else
184240Smckusick #include "../h/param.h"
194240Smckusick #include "../h/inode.h"
204240Smckusick #include "../h/fs.h"
216490Smckusick #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;
176*6534Smckusick 	if (!dflg) {
177*6534Smckusick 		for (i = 0; i < (unsigned)n; i++)
1784240Smckusick 			bmap[i] = 0;
179*6534Smckusick 		for (c = 0; c < sblock.fs_ncg; c++) {
1805382Smckusic 			cgd = cgtod(&sblock, c);
181*6534Smckusick 			if (c == 0)
182*6534Smckusick 				d = cgbase(&sblock, c);
183*6534Smckusick 			else
184*6534Smckusick 				d = cgsblock(&sblock, c);
185*6534Smckusick 			for (; d < cgd; d += sblock.fs_frag)
1865326Smckusic 				chk(d, "badcg", sblock.fs_bsize);
1875382Smckusic 			d = cgimin(&sblock, c);
1884240Smckusick 			while (cgd < d) {
1895326Smckusic 				chk(cgd, "cg", sblock.fs_bsize);
1905326Smckusic 				cgd += sblock.fs_frag;
1914240Smckusick 			}
1925382Smckusic 			d = cgdmin(&sblock, c);
1935326Smckusic 			for (; cgd < d; cgd += sblock.fs_frag)
1945326Smckusic 				chk(cgd, "inode", sblock.fs_bsize);
1954240Smckusick 			if (c == 0) {
196*6534Smckusick 				d += howmany(sblock.fs_cssize, sblock.fs_fsize);
197*6534Smckusick 				for (; cgd < d; cgd++)
198*6534Smckusick 					chk(cgd, "csum", sblock.fs_fsize);
1994240Smckusick 			}
2004240Smckusick 		}
2014240Smckusick 	}
2024240Smckusick 	cginit = 0;
2034240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2045382Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
2054240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
2064240Smckusick 		for (j=0; j < sblock.fs_ipg; j++) {
2074240Smckusick 			pass1(&itab[j]);
2084240Smckusick 			ino++;
2094240Smckusick 		}
2104240Smckusick 	}
2114240Smckusick 	ino = 0;
2124240Smckusick #ifndef STANDALONE
2134240Smckusick 	sync();
2144240Smckusick #endif
2155098Smckusic 	if (sflg) {
2165098Smckusic 		makecg();
2175098Smckusic 		close(fi);
2185098Smckusic #ifndef STANDALONE
2195098Smckusic 		if (bmap)
2205098Smckusic 			free(bmap);
2215098Smckusic #endif
2225098Smckusic 		return;
2235098Smckusic 	}
2244240Smckusick 	nffree = 0;
2254240Smckusick 	nbfree = 0;
2264240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2275382Smckusic 		cbase = cgbase(&sblock, c);
2285382Smckusic 		bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
2295326Smckusic 			sblock.fs_cgsize);
230*6534Smckusick 		if (cgrp.cg_magic != CG_MAGIC)
231*6534Smckusick 			printf("cg %d: bad magic number\n", c);
2325326Smckusic 		for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
2335326Smckusic 			if (isblock(&sblock, cgrp.cg_free,
2345326Smckusic 			    b / sblock.fs_frag)) {
2354240Smckusick 				nbfree++;
2365326Smckusic 				chk(cbase+b, "block", sblock.fs_bsize);
2374240Smckusick 			} else {
2385326Smckusic 				for (d = 0; d < sblock.fs_frag; d++)
2394240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
2405326Smckusic 						chk(cbase+b+d, "frag", sblock.fs_fsize);
2414240Smckusick 						nffree++;
2424240Smckusick 					}
2434240Smckusick 			}
2444240Smckusick 		}
2454240Smckusick 	}
2464240Smckusick 	close(fi);
2474240Smckusick #ifndef STANDALONE
2484240Smckusick 	if (bmap)
2494240Smckusick 		free(bmap);
2504240Smckusick #endif
2514240Smckusick 
2526286Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nlfile;
2534240Smckusick #ifndef STANDALONE
2546286Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
2556286Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
2564240Smckusick #else
2576286Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
2586286Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nlfile);
2594240Smckusick #endif
2605326Smckusic 	n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
2614240Smckusick #ifdef STANDALONE
2624240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2634240Smckusick 		n, nindir, niindir, nblock, nfrag);
2645326Smckusic 	printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
2654240Smckusick 	    nbfree, nffree);
2664240Smckusick #else
2674240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2684240Smckusick 		n, nindir, niindir, nblock, nfrag);
2695326Smckusic 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
2704240Smckusick 	    nbfree, nffree);
2714240Smckusick #endif
2724240Smckusick 	if(!dflg) {
2734240Smckusick 		n = 0;
2744410Smckusic 		for (d = 0; d < sblock.fs_size; d++)
2755326Smckusic 			if(!duped(d, sblock.fs_fsize)) {
2764240Smckusick 				if(mflg)
2774240Smckusick 					printf("%ld missing\n", d);
2784240Smckusick 				n++;
2794240Smckusick 			}
2804240Smckusick 		printf("missing%5ld\n", n);
2814240Smckusick 	}
2824240Smckusick }
2834240Smckusick 
2844240Smckusick pass1(ip)
2854410Smckusic 	register struct dinode *ip;
2864240Smckusick {
2875326Smckusic 	daddr_t ind1[MAXNINDIR];
2885326Smckusic 	daddr_t ind2[MAXNINDIR];
2894429Smckusic 	daddr_t db, ib;
2904429Smckusic 	register int i, j, k, siz;
2914240Smckusick 
2924240Smckusick 	i = ip->di_mode & IFMT;
2934790Smckusic 	if(i == 0)
2944240Smckusick 		return;
2954240Smckusick 	switch (i) {
2964240Smckusick 	case IFCHR:
2974240Smckusick 		ncfile++;
2984240Smckusick 		return;
2994240Smckusick 	case IFBLK:
3004240Smckusick 		nbfile++;
3014240Smckusick 		return;
3024240Smckusick 	case IFDIR:
3034240Smckusick 		ndfile++;
3044240Smckusick 		break;
3054240Smckusick 	case IFREG:
3064240Smckusick 		nrfile++;
3074240Smckusick 		break;
3086286Smckusick 	case IFLNK:
3096286Smckusick 		nlfile++;
3106286Smckusick 		break;
3114240Smckusick 	default:
3124240Smckusick 		printf("bad mode %u\n", ino);
3134240Smckusick 		return;
3144240Smckusick 	}
3154410Smckusic 	for (i = 0; i < NDADDR; i++) {
3164410Smckusic 		db = ip->di_db[i];
3174410Smckusic 		if (db == 0)
3184240Smckusick 			continue;
3195326Smckusic 		siz = dblksize(&sblock, ip, i);
3204429Smckusic 		chk(db, "data (block)", siz);
3215326Smckusic 		if (siz == sblock.fs_bsize)
3224429Smckusic 			nblock++;
3234429Smckusic 		else
3245326Smckusic 			nfrag += howmany(siz, sblock.fs_fsize);
3254240Smckusick 	}
3264410Smckusic 	for(i = 0; i < NIADDR; i++) {
3274410Smckusic 		ib = ip->di_ib[i];
3284410Smckusic 		if(ib == 0)
3294240Smckusick 			continue;
3305326Smckusic 		if (chk(ib, "1st indirect", sblock.fs_bsize))
3314410Smckusic 			continue;
3325326Smckusic 		bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
3334240Smckusick 		nindir++;
3345326Smckusic 		for (j = 0; j < NINDIR(&sblock); j++) {
3354410Smckusic 			ib = ind1[j];
3364410Smckusic 			if (ib == 0)
3374240Smckusick 				continue;
3384410Smckusic 			if (i == 0) {
3395326Smckusic 				siz = dblksize(&sblock, ip, NDADDR + j);
3404429Smckusic 				chk(ib, "data (large)", siz);
3415326Smckusic 				if (siz == sblock.fs_bsize)
3424429Smckusic 					nblock++;
3434429Smckusic 				else
3445326Smckusic 					nfrag += howmany(siz, sblock.fs_fsize);
3454240Smckusick 				continue;
3464240Smckusick 			}
3475326Smckusic 			if (chk(ib, "2nd indirect", sblock.fs_bsize))
3484410Smckusic 				continue;
3495326Smckusic 			bread(fsbtodb(&sblock, ib), (char *)ind2,
3505326Smckusic 				sblock.fs_bsize);
3514240Smckusick 			niindir++;
3525326Smckusic 			for (k = 0; k < NINDIR(&sblock); k++) {
3534410Smckusic 				ib = ind2[k];
3544410Smckusic 				if (ib == 0)
3554240Smckusick 					continue;
3565326Smckusic 				siz = dblksize(&sblock, ip,
3575326Smckusic 				    NDADDR + NINDIR(&sblock) * (i + j) + k);
3584429Smckusic 				chk(ib, "data (huge)", siz);
3595326Smckusic 				if (siz == sblock.fs_bsize)
3604429Smckusic 					nblock++;
3614429Smckusic 				else
3625326Smckusic 					nfrag += howmany(siz, sblock.fs_fsize);
3634240Smckusick 			}
3644240Smckusick 		}
3654240Smckusick 	}
3664240Smckusick }
3674240Smckusick 
3684429Smckusic chk(bno, s, size)
3694410Smckusic 	daddr_t bno;
3704410Smckusic 	char *s;
3714429Smckusic 	int size;
3724240Smckusick {
3734240Smckusick 	register n, cg;
3745957Smckusic 	int frags;
3754240Smckusick 
3765382Smckusic 	cg = dtog(&sblock, bno);
377*6534Smckusick 	if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) {
3784240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
3794240Smckusick 		return(1);
3804240Smckusick 	}
3815326Smckusic 	if (size == sblock.fs_bsize) {
3824429Smckusic 		if (duped(bno, size)) {
3834429Smckusic 			printf("%ld dup block; inode=%u, class=%s\n",
3844429Smckusic 			    bno, ino, s);
3855326Smckusic 			ndup += sblock.fs_frag;
3864429Smckusic 		}
3874429Smckusic 	} else {
3885957Smckusic 		frags = numfrags(&sblock, size);
3895957Smckusic 		for (n = 0; n < frags; n++) {
3905326Smckusic 			if (duped(bno + n, sblock.fs_fsize)) {
3914429Smckusic 				printf("%ld dup frag; inode=%u, class=%s\n",
3924429Smckusic 				    bno, ino, s);
3934429Smckusic 				ndup++;
3944429Smckusic 			}
3954429Smckusic 		}
3964240Smckusick 	}
3974240Smckusick 	for (n=0; blist[n] != -1; n++)
3984240Smckusick 		if (bno == blist[n])
3994240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
4004240Smckusick 	return(0);
4014240Smckusick }
4024240Smckusick 
4034429Smckusic duped(bno, size)
4044410Smckusic 	daddr_t bno;
4054429Smckusic 	int size;
4064240Smckusick {
4074240Smckusick 	if(dflg)
4084240Smckusick 		return(0);
4095326Smckusic 	if (size != sblock.fs_fsize && size != sblock.fs_bsize)
4104429Smckusic 		printf("bad size %d to duped\n", size);
4115326Smckusic 	if (size == sblock.fs_fsize) {
4124410Smckusic 		if (isset(bmap, bno))
4134410Smckusic 			return(1);
4144410Smckusic 		setbit(bmap, bno);
4154410Smckusic 		return (0);
4164410Smckusic 	}
4175326Smckusic 	if (bno % sblock.fs_frag != 0)
4184410Smckusic 		printf("bad bno %d to duped\n", bno);
4195326Smckusic 	if (isblock(&sblock, bmap, bno/sblock.fs_frag))
4204410Smckusic 		return (1);
4215326Smckusic 	setblock(&sblock, bmap, bno/sblock.fs_frag);
4224240Smckusick 	return(0);
4234240Smckusick }
4244240Smckusick 
4255098Smckusic makecg()
4265098Smckusic {
4275098Smckusic 	int c, blk;
428*6534Smckusick 	daddr_t dbase, d, dlower, dupper, dmax;
4295098Smckusic 	long i, j, s;
4305098Smckusic 	register struct csum *cs;
4315098Smckusic 	register struct dinode *dp;
4325098Smckusic 
4335098Smckusic 	sblock.fs_cstotal.cs_nbfree = 0;
4345098Smckusic 	sblock.fs_cstotal.cs_nffree = 0;
4355098Smckusic 	sblock.fs_cstotal.cs_nifree = 0;
4365098Smckusic 	sblock.fs_cstotal.cs_ndir = 0;
4375098Smckusic 	for (c = 0; c < sblock.fs_ncg; c++) {
4385382Smckusic 		dbase = cgbase(&sblock, c);
4395098Smckusic 		dmax = dbase + sblock.fs_fpg;
4405410Smckusic 		if (dmax > sblock.fs_size) {
4415410Smckusic 			for ( ; dmax >= sblock.fs_size; dmax--)
4425400Smckusic 				clrbit(cgrp.cg_free, dmax - dbase);
4435410Smckusic 			dmax++;
4445410Smckusic 		}
445*6534Smckusick 		dlower = cgsblock(&sblock, c) - dbase;
446*6534Smckusick 		dupper = cgdmin(&sblock, c) - dbase;
4475326Smckusic 		cs = &sblock.fs_cs(&sblock, c);
4485098Smckusic 		cgrp.cg_time = time(0);
4495098Smckusic 		cgrp.cg_magic = CG_MAGIC;
4505098Smckusic 		cgrp.cg_cgx = c;
4515098Smckusic 		cgrp.cg_ncyl = sblock.fs_cpg;
4525098Smckusic 		cgrp.cg_niblk = sblock.fs_ipg;
4535098Smckusic 		cgrp.cg_ndblk = dmax - dbase;
4545098Smckusic 		cgrp.cg_cs.cs_ndir = 0;
4555098Smckusic 		cgrp.cg_cs.cs_nffree = 0;
4565098Smckusic 		cgrp.cg_cs.cs_nbfree = 0;
4575098Smckusic 		cgrp.cg_cs.cs_nifree = 0;
458*6534Smckusick 		cgrp.cg_rotor = 0;
459*6534Smckusick 		cgrp.cg_frotor = 0;
4605098Smckusic 		cgrp.cg_irotor = 0;
4615326Smckusic 		for (i = 0; i < sblock.fs_frag; i++)
4625098Smckusic 			cgrp.cg_frsum[i] = 0;
4635382Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
4645098Smckusic 		      sblock.fs_ipg * sizeof(struct dinode));
4655098Smckusic 		for (i = 0; i < sblock.fs_ipg; i++) {
4665945Smckusic 			cgrp.cg_cs.cs_nifree++;
4675945Smckusic 			clrbit(cgrp.cg_iused, i);
4685098Smckusic 			dp = &itab[i];
4695098Smckusic 			if ((dp->di_mode & IFMT) != 0) {
4705098Smckusic 				if ((dp->di_mode & IFMT) == IFDIR)
4715098Smckusic 					cgrp.cg_cs.cs_ndir++;
4725945Smckusic 				cgrp.cg_cs.cs_nifree--;
4735098Smckusic 				setbit(cgrp.cg_iused, i);
4745098Smckusic 				continue;
4755098Smckusic 			}
4765098Smckusic 		}
4775098Smckusic 		while (i < MAXIPG) {
4785098Smckusic 			clrbit(cgrp.cg_iused, i);
4795098Smckusic 			i++;
4805098Smckusic 		}
4815338Smckusic 		if (c == 0)
4825338Smckusic 			for (i = 0; i < ROOTINO; i++) {
4835338Smckusic 				setbit(cgrp.cg_iused, i);
4845338Smckusic 				cgrp.cg_cs.cs_nifree--;
4855338Smckusic 			}
4865372Smckusic 		for (s = 0; s < MAXCPG; s++) {
4875372Smckusic 			cgrp.cg_btot[s] = 0;
4885098Smckusic 			for (i = 0; i < NRPOS; i++)
4895098Smckusic 				cgrp.cg_b[s][i] = 0;
4905372Smckusic 		}
4915098Smckusic 		if (c == 0) {
492*6534Smckusick 			dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
4935098Smckusic 		}
494*6534Smckusick 		for (d = dlower; d < dupper; d++)
4955098Smckusic 			clrbit(cgrp.cg_free, d);
496*6534Smckusick 		for (d = 0; (d + sblock.fs_frag) <= dmax - dbase;
497*6534Smckusick 		    d += sblock.fs_frag) {
4985098Smckusic 			j = 0;
4995326Smckusic 			for (i = 0; i < sblock.fs_frag; i++) {
500*6534Smckusick 				if (!isset(bmap, dbase + d + i)) {
501*6534Smckusick 					setbit(cgrp.cg_free, d + i);
5025098Smckusic 					j++;
5035098Smckusic 				} else
5045098Smckusic 					clrbit(cgrp.cg_free, d+i);
5055098Smckusic 			}
5065326Smckusic 			if (j == sblock.fs_frag) {
5075098Smckusic 				cgrp.cg_cs.cs_nbfree++;
5085372Smckusic 				cgrp.cg_btot[cbtocylno(&sblock, d)]++;
5095364Smckusic 				cgrp.cg_b[cbtocylno(&sblock, d)]
5105364Smckusic 				    [cbtorpos(&sblock, d)]++;
5115098Smckusic 			} else if (j > 0) {
5125098Smckusic 				cgrp.cg_cs.cs_nffree += j;
513*6534Smckusick 				blk = blkmap(&sblock, cgrp.cg_free, d);
5145326Smckusic 				fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5155098Smckusic 			}
5165098Smckusic 		}
5175098Smckusic 		for (j = d; d < dmax - dbase; d++) {
518*6534Smckusick 			if (!isset(bmap, dbase + d)) {
5195098Smckusic 				setbit(cgrp.cg_free, d);
5205098Smckusic 				cgrp.cg_cs.cs_nffree++;
5215098Smckusic 			} else
5225098Smckusic 				clrbit(cgrp.cg_free, d);
5235098Smckusic 		}
5245098Smckusic 		if (j != d) {
525*6534Smckusick 			blk = blkmap(&sblock, cgrp.cg_free, j);
5265326Smckusic 			fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5275098Smckusic 		}
5285326Smckusic 		for (; d < MAXBPG(&sblock); d++)
5295098Smckusic 			clrbit(cgrp.cg_free, d);
5305098Smckusic 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
5315098Smckusic 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
5325098Smckusic 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
5335098Smckusic 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
5345098Smckusic 		*cs = cgrp.cg_cs;
5355382Smckusic 		bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp,
5365326Smckusic 			sblock.fs_cgsize);
5375098Smckusic 	}
538*6534Smckusick 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
539*6534Smckusick 		bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
540*6534Smckusick 		    (char *)sblock.fs_csp[j],
541*6534Smckusick 		    sblock.fs_cssize - i < sblock.fs_bsize ?
542*6534Smckusick 		    sblock.fs_cssize - i : sblock.fs_bsize);
5435098Smckusic 	}
5445098Smckusic 	sblock.fs_ronly = 0;
5455098Smckusic 	sblock.fs_fmod = 0;
5465349Smckusic 	bwrite(SBLOCK, (char *)&sblock, SBSIZE);
5475098Smckusic }
5485098Smckusic 
5495098Smckusic /*
5505098Smckusic  * update the frsum fields to reflect addition or deletion
5515098Smckusic  * of some frags
5525098Smckusic  */
5535326Smckusic fragacct(fs, fragmap, fraglist, cnt)
5545326Smckusic 	struct fs *fs;
5555098Smckusic 	int fragmap;
5565098Smckusic 	long fraglist[];
5575098Smckusic 	int cnt;
5585098Smckusic {
5595098Smckusic 	int inblk;
5605098Smckusic 	register int field, subfield;
5615098Smckusic 	register int siz, pos;
5625098Smckusic 
5635326Smckusic 	inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
5645098Smckusic 	fragmap <<= 1;
5655326Smckusic 	for (siz = 1; siz < fs->fs_frag; siz++) {
5666291Smckusick 		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
5675098Smckusic 			continue;
5685098Smckusic 		field = around[siz];
5695098Smckusic 		subfield = inside[siz];
5705326Smckusic 		for (pos = siz; pos <= fs->fs_frag; pos++) {
5715098Smckusic 			if ((fragmap & field) == subfield) {
5725098Smckusic 				fraglist[siz] += cnt;
5735098Smckusic 				pos += siz;
5745098Smckusic 				field <<= siz;
5755098Smckusic 				subfield <<= siz;
5765098Smckusic 			}
5775098Smckusic 			field <<= 1;
5785098Smckusic 			subfield <<= 1;
5795098Smckusic 		}
5805098Smckusic 	}
5815098Smckusic }
5825098Smckusic 
5835326Smckusic getsb(fs, file)
5845326Smckusic 	register struct fs *fs;
5855326Smckusic 	char *file;
5865326Smckusic {
587*6534Smckusick 	int i, j, size;
5885326Smckusic 
5895349Smckusic 	if (bread(SBLOCK, fs, SBSIZE)) {
5905326Smckusic 		printf("bad super block");
5915326Smckusic 		perror(file);
5925326Smckusic 		nerror |= 04;
5935326Smckusic 		return;
5945326Smckusic 	}
5955326Smckusic 	if (fs->fs_magic != FS_MAGIC) {
5965326Smckusic 		printf("%s: bad magic number\n", file);
5975326Smckusic 		nerror |= 04;
5985326Smckusic 		return;
5995326Smckusic 	}
600*6534Smckusick 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
601*6534Smckusick 		size = sblock.fs_cssize - i < sblock.fs_bsize ?
602*6534Smckusick 		    sblock.fs_cssize - i : sblock.fs_bsize;
603*6534Smckusick 		sblock.fs_csp[j] = (struct csum *)calloc(1, size);
604*6534Smckusick 		bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)),
605*6534Smckusick 		      (char *)fs->fs_csp[j], size);
6065326Smckusic 	}
6075326Smckusic }
6085326Smckusic 
6095098Smckusic bwrite(blk, buf, size)
6105098Smckusic 	char *buf;
6115098Smckusic 	daddr_t blk;
6125098Smckusic 	register size;
6135098Smckusic {
6145326Smckusic 	if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
6155098Smckusic 		perror("FS SEEK");
6165098Smckusic 		return(1);
6175098Smckusic 	}
6185098Smckusic 	if (write(fi, buf, size) != size) {
6195098Smckusic 		perror("FS WRITE");
6205098Smckusic 		return(1);
6215098Smckusic 	}
6225326Smckusic 	return (0);
6235098Smckusic }
6245098Smckusic 
6254240Smckusick bread(bno, buf, cnt)
6264410Smckusic 	daddr_t bno;
6274410Smckusic 	char *buf;
6284240Smckusick {
6294240Smckusick 	register i;
6304240Smckusick 
6315326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
6324240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
6335098Smckusic 		if (sflg) {
6345098Smckusic 			printf("No Update\n");
6355098Smckusic 			sflg = 0;
6365098Smckusic 		}
6375326Smckusic 		for(i=0; i<sblock.fs_bsize; i++)
6384240Smckusick 			buf[i] = 0;
6395326Smckusic 		return (1);
6404240Smckusick 	}
6415326Smckusic 	return (0);
6424240Smckusick }
6435326Smckusic 
6445326Smckusic /*
6455326Smckusic  * block operations
6465326Smckusic  */
6475326Smckusic 
6485326Smckusic isblock(fs, cp, h)
6495326Smckusic 	struct fs *fs;
6505326Smckusic 	unsigned char *cp;
6515326Smckusic 	int h;
6525326Smckusic {
6535326Smckusic 	unsigned char mask;
6545326Smckusic 
6555326Smckusic 	switch (fs->fs_frag) {
6565326Smckusic 	case 8:
6575326Smckusic 		return (cp[h] == 0xff);
6585326Smckusic 	case 4:
6595326Smckusic 		mask = 0x0f << ((h & 0x1) << 2);
6605326Smckusic 		return ((cp[h >> 1] & mask) == mask);
6615326Smckusic 	case 2:
6625326Smckusic 		mask = 0x03 << ((h & 0x3) << 1);
6635326Smckusic 		return ((cp[h >> 2] & mask) == mask);
6645326Smckusic 	case 1:
6655326Smckusic 		mask = 0x01 << (h & 0x7);
6665326Smckusic 		return ((cp[h >> 3] & mask) == mask);
6675326Smckusic 	default:
6685326Smckusic 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
6695326Smckusic 		return;
6705326Smckusic 	}
6715326Smckusic }
6725326Smckusic 
6735326Smckusic setblock(fs, cp, h)
6745326Smckusic 	struct fs *fs;
6755326Smckusic 	unsigned char *cp;
6765326Smckusic 	int h;
6775326Smckusic {
6785326Smckusic 	switch (fs->fs_frag) {
6795326Smckusic 	case 8:
6805326Smckusic 		cp[h] = 0xff;
6815326Smckusic 		return;
6825326Smckusic 	case 4:
6835326Smckusic 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
6845326Smckusic 		return;
6855326Smckusic 	case 2:
6865326Smckusic 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
6875326Smckusic 		return;
6885326Smckusic 	case 1:
6895326Smckusic 		cp[h >> 3] |= (0x01 << (h & 0x7));
6905326Smckusic 		return;
6915326Smckusic 	default:
6925326Smckusic 		fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
6935326Smckusic 		return;
6945326Smckusic 	}
6955326Smckusic }
6966490Smckusick 
6976490Smckusick /*	tables.c	4.1	82/03/25	*/
6986490Smckusick 
6996490Smckusick /* merged into kernel:	tables.c 2.1 3/25/82 */
7006490Smckusick 
7016490Smckusick /* last monet version:	partab.c	4.2	81/03/08	*/
7026490Smckusick 
7036490Smckusick /*
7046490Smckusick  * bit patterns for identifying fragments in the block map
7056490Smckusick  * used as ((map & around) == inside)
7066490Smckusick  */
7076490Smckusick int around[9] = {
7086490Smckusick 	0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
7096490Smckusick };
7106490Smckusick int inside[9] = {
7116490Smckusick 	0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
7126490Smckusick };
7136490Smckusick 
7146490Smckusick /*
7156490Smckusick  * given a block map bit pattern, the frag tables tell whether a
7166490Smckusick  * particular size fragment is available.
7176490Smckusick  *
7186490Smckusick  * used as:
7196490Smckusick  * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] {
7206490Smckusick  *	at least one fragment of the indicated size is available
7216490Smckusick  * }
7226490Smckusick  *
7236490Smckusick  * These tables are used by the scanc instruction on the VAX to
7246490Smckusick  * quickly find an appropriate fragment.
7256490Smckusick  */
7266490Smckusick 
7276490Smckusick unsigned char fragtbl124[256] = {
7286490Smckusick 	0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
7296490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
7306490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7316490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7326490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7336490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7346490Smckusick 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
7356490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
7366490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7376490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7386490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7396490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7406490Smckusick 	0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e,
7416490Smckusick 	0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae,
7426490Smckusick 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
7436490Smckusick 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
7446490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7456490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7466490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7476490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7486490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7496490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7506490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
7516490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
7526490Smckusick 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
7536490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
7546490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
7556490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
7566490Smckusick 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
7576490Smckusick 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
7586490Smckusick 	0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce,
7596490Smckusick 	0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
7606490Smckusick };
7616490Smckusick 
7626490Smckusick unsigned char fragtbl8[256] = {
7636490Smckusick 	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
7646490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
7656490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7666490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
7676490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7686490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
7696490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
7706490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
7716490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7726490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
7736490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7746490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
7756490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
7766490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
7776490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
7786490Smckusick 	0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40,
7796490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7806490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
7816490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7826490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
7836490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
7846490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
7856490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
7866490Smckusick 	0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
7876490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
7886490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
7896490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
7906490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12,
7916490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
7926490Smckusick 	0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c,
7936490Smckusick 	0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c,
7946490Smckusick 	0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
7956490Smckusick };
7966490Smckusick 
7976490Smckusick /*
7986490Smckusick  * the actual fragtbl array
7996490Smckusick  */
8006490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = {
8016490Smckusick 	0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
8026490Smckusick };
803