xref: /csrg-svn/sbin/icheck/icheck.c (revision 8143)
1*8143Smckusick static	char *sccsid = "@(#)icheck.c	2.3 (Berkeley) 09/10/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;
1766534Smckusick 	if (!dflg) {
1776534Smckusick 		for (i = 0; i < (unsigned)n; i++)
1784240Smckusick 			bmap[i] = 0;
1796534Smckusick 		for (c = 0; c < sblock.fs_ncg; c++) {
1805382Smckusic 			cgd = cgtod(&sblock, c);
1816534Smckusick 			if (c == 0)
1826534Smckusick 				d = cgbase(&sblock, c);
1836534Smckusick 			else
1846534Smckusick 				d = cgsblock(&sblock, c);
1856534Smckusick 			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) {
1966534Smckusick 				d += howmany(sblock.fs_cssize, sblock.fs_fsize);
1976534Smckusick 				for (; cgd < d; cgd++)
1986534Smckusick 					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);
2306534Smckusick 		if (cgrp.cg_magic != CG_MAGIC)
2316534Smckusick 			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);
3776534Smckusick 	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;
4286534Smckusick 	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 		}
4456534Smckusick 		dlower = cgsblock(&sblock, c) - dbase;
4466534Smckusick 		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;
451*8143Smckusick 		if (c == sblock.fs_ncg - 1)
452*8143Smckusick 			cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg;
453*8143Smckusick 		else
454*8143Smckusick 			cgrp.cg_ncyl = sblock.fs_cpg;
4555098Smckusic 		cgrp.cg_niblk = sblock.fs_ipg;
4565098Smckusic 		cgrp.cg_ndblk = dmax - dbase;
4575098Smckusic 		cgrp.cg_cs.cs_ndir = 0;
4585098Smckusic 		cgrp.cg_cs.cs_nffree = 0;
4595098Smckusic 		cgrp.cg_cs.cs_nbfree = 0;
4605098Smckusic 		cgrp.cg_cs.cs_nifree = 0;
4616534Smckusick 		cgrp.cg_rotor = 0;
4626534Smckusick 		cgrp.cg_frotor = 0;
4635098Smckusic 		cgrp.cg_irotor = 0;
4645326Smckusic 		for (i = 0; i < sblock.fs_frag; i++)
4655098Smckusic 			cgrp.cg_frsum[i] = 0;
4665382Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
4675098Smckusic 		      sblock.fs_ipg * sizeof(struct dinode));
4685098Smckusic 		for (i = 0; i < sblock.fs_ipg; i++) {
4695945Smckusic 			cgrp.cg_cs.cs_nifree++;
4705945Smckusic 			clrbit(cgrp.cg_iused, i);
4715098Smckusic 			dp = &itab[i];
4725098Smckusic 			if ((dp->di_mode & IFMT) != 0) {
4735098Smckusic 				if ((dp->di_mode & IFMT) == IFDIR)
4745098Smckusic 					cgrp.cg_cs.cs_ndir++;
4755945Smckusic 				cgrp.cg_cs.cs_nifree--;
4765098Smckusic 				setbit(cgrp.cg_iused, i);
4775098Smckusic 				continue;
4785098Smckusic 			}
4795098Smckusic 		}
4805098Smckusic 		while (i < MAXIPG) {
4815098Smckusic 			clrbit(cgrp.cg_iused, i);
4825098Smckusic 			i++;
4835098Smckusic 		}
4845338Smckusic 		if (c == 0)
4855338Smckusic 			for (i = 0; i < ROOTINO; i++) {
4865338Smckusic 				setbit(cgrp.cg_iused, i);
4875338Smckusic 				cgrp.cg_cs.cs_nifree--;
4885338Smckusic 			}
4895372Smckusic 		for (s = 0; s < MAXCPG; s++) {
4905372Smckusic 			cgrp.cg_btot[s] = 0;
4915098Smckusic 			for (i = 0; i < NRPOS; i++)
4925098Smckusic 				cgrp.cg_b[s][i] = 0;
4935372Smckusic 		}
4945098Smckusic 		if (c == 0) {
4956534Smckusick 			dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
4965098Smckusic 		}
4976534Smckusick 		for (d = dlower; d < dupper; d++)
4985098Smckusic 			clrbit(cgrp.cg_free, d);
4996534Smckusick 		for (d = 0; (d + sblock.fs_frag) <= dmax - dbase;
5006534Smckusick 		    d += sblock.fs_frag) {
5015098Smckusic 			j = 0;
5025326Smckusic 			for (i = 0; i < sblock.fs_frag; i++) {
5036534Smckusick 				if (!isset(bmap, dbase + d + i)) {
5046534Smckusick 					setbit(cgrp.cg_free, d + i);
5055098Smckusic 					j++;
5065098Smckusic 				} else
5075098Smckusic 					clrbit(cgrp.cg_free, d+i);
5085098Smckusic 			}
5095326Smckusic 			if (j == sblock.fs_frag) {
5105098Smckusic 				cgrp.cg_cs.cs_nbfree++;
5115372Smckusic 				cgrp.cg_btot[cbtocylno(&sblock, d)]++;
5125364Smckusic 				cgrp.cg_b[cbtocylno(&sblock, d)]
5135364Smckusic 				    [cbtorpos(&sblock, d)]++;
5145098Smckusic 			} else if (j > 0) {
5155098Smckusic 				cgrp.cg_cs.cs_nffree += j;
5166534Smckusick 				blk = blkmap(&sblock, cgrp.cg_free, d);
5175326Smckusic 				fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5185098Smckusic 			}
5195098Smckusic 		}
5205098Smckusic 		for (j = d; d < dmax - dbase; d++) {
5216534Smckusick 			if (!isset(bmap, dbase + d)) {
5225098Smckusic 				setbit(cgrp.cg_free, d);
5235098Smckusic 				cgrp.cg_cs.cs_nffree++;
5245098Smckusic 			} else
5255098Smckusic 				clrbit(cgrp.cg_free, d);
5265098Smckusic 		}
527*8143Smckusick 		for (; d % sblock.fs_frag != 0; d++)
528*8143Smckusick 			clrbit(cgrp.cg_free, d);
5295098Smckusic 		if (j != d) {
5306534Smckusick 			blk = blkmap(&sblock, cgrp.cg_free, j);
5315326Smckusic 			fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5325098Smckusic 		}
533*8143Smckusick 		for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++)
534*8143Smckusick 			clrblock(&sblock, cgrp.cg_free, d);
5355098Smckusic 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
5365098Smckusic 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
5375098Smckusic 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
5385098Smckusic 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
5395098Smckusic 		*cs = cgrp.cg_cs;
5405382Smckusic 		bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp,
5415326Smckusic 			sblock.fs_cgsize);
5425098Smckusic 	}
5436534Smckusick 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
5446534Smckusick 		bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
5456534Smckusick 		    (char *)sblock.fs_csp[j],
5466534Smckusick 		    sblock.fs_cssize - i < sblock.fs_bsize ?
5476534Smckusick 		    sblock.fs_cssize - i : sblock.fs_bsize);
5485098Smckusic 	}
5495098Smckusic 	sblock.fs_ronly = 0;
5505098Smckusic 	sblock.fs_fmod = 0;
5515349Smckusic 	bwrite(SBLOCK, (char *)&sblock, SBSIZE);
5525098Smckusic }
5535098Smckusic 
5545098Smckusic /*
5555098Smckusic  * update the frsum fields to reflect addition or deletion
5565098Smckusic  * of some frags
5575098Smckusic  */
5585326Smckusic fragacct(fs, fragmap, fraglist, cnt)
5595326Smckusic 	struct fs *fs;
5605098Smckusic 	int fragmap;
5615098Smckusic 	long fraglist[];
5625098Smckusic 	int cnt;
5635098Smckusic {
5645098Smckusic 	int inblk;
5655098Smckusic 	register int field, subfield;
5665098Smckusic 	register int siz, pos;
5675098Smckusic 
5685326Smckusic 	inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
5695098Smckusic 	fragmap <<= 1;
5705326Smckusic 	for (siz = 1; siz < fs->fs_frag; siz++) {
5716291Smckusick 		if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
5725098Smckusic 			continue;
5735098Smckusic 		field = around[siz];
5745098Smckusic 		subfield = inside[siz];
5755326Smckusic 		for (pos = siz; pos <= fs->fs_frag; pos++) {
5765098Smckusic 			if ((fragmap & field) == subfield) {
5775098Smckusic 				fraglist[siz] += cnt;
5785098Smckusic 				pos += siz;
5795098Smckusic 				field <<= siz;
5805098Smckusic 				subfield <<= siz;
5815098Smckusic 			}
5825098Smckusic 			field <<= 1;
5835098Smckusic 			subfield <<= 1;
5845098Smckusic 		}
5855098Smckusic 	}
5865098Smckusic }
5875098Smckusic 
5885326Smckusic getsb(fs, file)
5895326Smckusic 	register struct fs *fs;
5905326Smckusic 	char *file;
5915326Smckusic {
5926534Smckusick 	int i, j, size;
5935326Smckusic 
5945349Smckusic 	if (bread(SBLOCK, fs, SBSIZE)) {
5955326Smckusic 		printf("bad super block");
5965326Smckusic 		perror(file);
5975326Smckusic 		nerror |= 04;
5985326Smckusic 		return;
5995326Smckusic 	}
6005326Smckusic 	if (fs->fs_magic != FS_MAGIC) {
6015326Smckusic 		printf("%s: bad magic number\n", file);
6025326Smckusic 		nerror |= 04;
6035326Smckusic 		return;
6045326Smckusic 	}
6056534Smckusick 	for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
6066534Smckusick 		size = sblock.fs_cssize - i < sblock.fs_bsize ?
6076534Smckusick 		    sblock.fs_cssize - i : sblock.fs_bsize;
6086534Smckusick 		sblock.fs_csp[j] = (struct csum *)calloc(1, size);
6096534Smckusick 		bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)),
6106534Smckusick 		      (char *)fs->fs_csp[j], size);
6115326Smckusic 	}
6125326Smckusic }
6135326Smckusic 
6145098Smckusic bwrite(blk, buf, size)
6155098Smckusic 	char *buf;
6165098Smckusic 	daddr_t blk;
6175098Smckusic 	register size;
6185098Smckusic {
6195326Smckusic 	if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
6205098Smckusic 		perror("FS SEEK");
6215098Smckusic 		return(1);
6225098Smckusic 	}
6235098Smckusic 	if (write(fi, buf, size) != size) {
6245098Smckusic 		perror("FS WRITE");
6255098Smckusic 		return(1);
6265098Smckusic 	}
6275326Smckusic 	return (0);
6285098Smckusic }
6295098Smckusic 
6304240Smckusick bread(bno, buf, cnt)
6314410Smckusic 	daddr_t bno;
6324410Smckusic 	char *buf;
6334240Smckusick {
6344240Smckusick 	register i;
6354240Smckusick 
6365326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
6374240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
6385098Smckusic 		if (sflg) {
6395098Smckusic 			printf("No Update\n");
6405098Smckusic 			sflg = 0;
6415098Smckusic 		}
6425326Smckusic 		for(i=0; i<sblock.fs_bsize; i++)
6434240Smckusick 			buf[i] = 0;
6445326Smckusic 		return (1);
6454240Smckusick 	}
6465326Smckusic 	return (0);
6474240Smckusick }
6485326Smckusic 
6495326Smckusic /*
650*8143Smckusick  * check if a block is available
6515326Smckusic  */
6525326Smckusic isblock(fs, cp, h)
6535326Smckusic 	struct fs *fs;
6545326Smckusic 	unsigned char *cp;
6555326Smckusic 	int h;
6565326Smckusic {
6575326Smckusic 	unsigned char mask;
6585326Smckusic 
6595326Smckusic 	switch (fs->fs_frag) {
6605326Smckusic 	case 8:
6615326Smckusic 		return (cp[h] == 0xff);
6625326Smckusic 	case 4:
6635326Smckusic 		mask = 0x0f << ((h & 0x1) << 2);
6645326Smckusic 		return ((cp[h >> 1] & mask) == mask);
6655326Smckusic 	case 2:
6665326Smckusic 		mask = 0x03 << ((h & 0x3) << 1);
6675326Smckusic 		return ((cp[h >> 2] & mask) == mask);
6685326Smckusic 	case 1:
6695326Smckusic 		mask = 0x01 << (h & 0x7);
6705326Smckusic 		return ((cp[h >> 3] & mask) == mask);
6715326Smckusic 	default:
672*8143Smckusick #ifdef STANDALONE
673*8143Smckusick 		printf("isblock bad fs_frag %d\n", fs->fs_frag);
674*8143Smckusick #else
6755326Smckusic 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
676*8143Smckusick #endif
6775326Smckusic 		return;
6785326Smckusic 	}
6795326Smckusic }
6805326Smckusic 
681*8143Smckusick /*
682*8143Smckusick  * take a block out of the map
683*8143Smckusick  */
684*8143Smckusick clrblock(fs, cp, h)
685*8143Smckusick 	struct fs *fs;
686*8143Smckusick 	unsigned char *cp;
687*8143Smckusick 	int h;
688*8143Smckusick {
689*8143Smckusick 	switch ((fs)->fs_frag) {
690*8143Smckusick 	case 8:
691*8143Smckusick 		cp[h] = 0;
692*8143Smckusick 		return;
693*8143Smckusick 	case 4:
694*8143Smckusick 		cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
695*8143Smckusick 		return;
696*8143Smckusick 	case 2:
697*8143Smckusick 		cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
698*8143Smckusick 		return;
699*8143Smckusick 	case 1:
700*8143Smckusick 		cp[h >> 3] &= ~(0x01 << (h & 0x7));
701*8143Smckusick 		return;
702*8143Smckusick 	default:
703*8143Smckusick #ifdef STANDALONE
704*8143Smckusick 		printf("clrblock bad fs_frag %d\n", fs->fs_frag);
705*8143Smckusick #else
706*8143Smckusick 		fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
707*8143Smckusick #endif
708*8143Smckusick 		return;
709*8143Smckusick 	}
710*8143Smckusick }
711*8143Smckusick 
712*8143Smckusick /*
713*8143Smckusick  * put a block into the map
714*8143Smckusick  */
7155326Smckusic setblock(fs, cp, h)
7165326Smckusic 	struct fs *fs;
7175326Smckusic 	unsigned char *cp;
7185326Smckusic 	int h;
7195326Smckusic {
7205326Smckusic 	switch (fs->fs_frag) {
7215326Smckusic 	case 8:
7225326Smckusic 		cp[h] = 0xff;
7235326Smckusic 		return;
7245326Smckusic 	case 4:
7255326Smckusic 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
7265326Smckusic 		return;
7275326Smckusic 	case 2:
7285326Smckusic 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
7295326Smckusic 		return;
7305326Smckusic 	case 1:
7315326Smckusic 		cp[h >> 3] |= (0x01 << (h & 0x7));
7325326Smckusic 		return;
7335326Smckusic 	default:
734*8143Smckusick #ifdef STANDALONE
735*8143Smckusick 		printf("setblock bad fs_frag %d\n", fs->fs_frag);
736*8143Smckusick #else
7375326Smckusic 		fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
738*8143Smckusick #endif
7395326Smckusic 		return;
7405326Smckusic 	}
7415326Smckusic }
7426490Smckusick 
7436490Smckusick /*	tables.c	4.1	82/03/25	*/
7446490Smckusick 
7456490Smckusick /* merged into kernel:	tables.c 2.1 3/25/82 */
7466490Smckusick 
7476490Smckusick /* last monet version:	partab.c	4.2	81/03/08	*/
7486490Smckusick 
7496490Smckusick /*
7506490Smckusick  * bit patterns for identifying fragments in the block map
7516490Smckusick  * used as ((map & around) == inside)
7526490Smckusick  */
7536490Smckusick int around[9] = {
7546490Smckusick 	0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
7556490Smckusick };
7566490Smckusick int inside[9] = {
7576490Smckusick 	0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
7586490Smckusick };
7596490Smckusick 
7606490Smckusick /*
7616490Smckusick  * given a block map bit pattern, the frag tables tell whether a
7626490Smckusick  * particular size fragment is available.
7636490Smckusick  *
7646490Smckusick  * used as:
7656490Smckusick  * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] {
7666490Smckusick  *	at least one fragment of the indicated size is available
7676490Smckusick  * }
7686490Smckusick  *
7696490Smckusick  * These tables are used by the scanc instruction on the VAX to
7706490Smckusick  * quickly find an appropriate fragment.
7716490Smckusick  */
7726490Smckusick 
7736490Smckusick unsigned char fragtbl124[256] = {
7746490Smckusick 	0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
7756490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
7766490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7776490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7786490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7796490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7806490Smckusick 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
7816490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
7826490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7836490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7846490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7856490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7866490Smckusick 	0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e,
7876490Smckusick 	0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae,
7886490Smckusick 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
7896490Smckusick 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
7906490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7916490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7926490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7936490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7946490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
7956490Smckusick 	0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
7966490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
7976490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
7986490Smckusick 	0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
7996490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
8006490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
8016490Smckusick 	0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
8026490Smckusick 	0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
8036490Smckusick 	0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
8046490Smckusick 	0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce,
8056490Smckusick 	0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
8066490Smckusick };
8076490Smckusick 
8086490Smckusick unsigned char fragtbl8[256] = {
8096490Smckusick 	0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
8106490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
8116490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8126490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
8136490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8146490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
8156490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
8166490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
8176490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8186490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
8196490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8206490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
8216490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
8226490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
8236490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
8246490Smckusick 	0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40,
8256490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8266490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
8276490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8286490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
8296490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
8306490Smckusick 	0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
8316490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
8326490Smckusick 	0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
8336490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
8346490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
8356490Smckusick 	0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
8366490Smckusick 	0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12,
8376490Smckusick 	0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
8386490Smckusick 	0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c,
8396490Smckusick 	0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c,
8406490Smckusick 	0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
8416490Smckusick };
8426490Smckusick 
8436490Smckusick /*
8446490Smckusick  * the actual fragtbl array
8456490Smckusick  */
8466490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = {
8476490Smckusick 	0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
8486490Smckusick };
849