xref: /csrg-svn/sbin/icheck/icheck.c (revision 5098)
1*5098Smckusic static	char *sccsid = "@(#)icheck.c	1.9 (Berkeley) 11/27/81";
24410Smckusic 
34240Smckusick /*
44240Smckusick  * icheck
54240Smckusick  */
64240Smckusick #define	NB	500
74240Smckusick #define	MAXFN	500
84240Smckusick 
94240Smckusick #ifndef STANDALONE
104240Smckusick #include <stdio.h>
114240Smckusick #endif
124240Smckusick #include "../h/param.h"
134240Smckusick #include "../h/inode.h"
144240Smckusick #include "../h/fs.h"
154240Smckusick 
164240Smckusick union {
174240Smckusick 	struct	fs sb;
184240Smckusick 	char pad[BSIZE];
194240Smckusick } sbun;
204240Smckusick #define	sblock sbun.sb
214240Smckusick 
224240Smckusick union {
234240Smckusick 	struct	cg cg;
244240Smckusick 	char pad[BSIZE];
254240Smckusick } cgun;
264240Smckusick #define	cgrp cgun.cg
274240Smckusick 
284240Smckusick struct	dinode	itab[MAXIPG];
294240Smckusick daddr_t	blist[NB];
304240Smckusick char	*bmap;
314240Smckusick 
324240Smckusick int	mflg;
33*5098Smckusic int	sflg;
344240Smckusick int	dflg;
354240Smckusick int	fi;
364240Smckusick ino_t	ino;
374240Smckusick int	cginit;
384240Smckusick 
394240Smckusick ino_t	nrfile;
404240Smckusick ino_t	ndfile;
414240Smckusick ino_t	nbfile;
424240Smckusick ino_t	ncfile;
434240Smckusick ino_t	nmcfile;
444240Smckusick 
454240Smckusick daddr_t	nblock;
464240Smckusick daddr_t	nfrag;
474240Smckusick daddr_t	nindir;
484240Smckusick daddr_t	niindir;
494240Smckusick 
504240Smckusick daddr_t	nffree;
514240Smckusick daddr_t	nbfree;
524240Smckusick 
534240Smckusick daddr_t	ndup;
544240Smckusick 
554240Smckusick int	nerror;
564240Smckusick 
57*5098Smckusic extern int inside[], around[];
58*5098Smckusic extern unsigned char fragtbl[];
59*5098Smckusic 
604240Smckusick long	atol();
614240Smckusick #ifndef STANDALONE
624240Smckusick char	*malloc();
63*5098Smckusic char	*calloc();
644240Smckusick #endif
654240Smckusick 
664240Smckusick main(argc, argv)
67*5098Smckusic 	int argc;
68*5098Smckusic 	char *argv[];
694240Smckusick {
704240Smckusick 	register i;
714240Smckusick 	long n;
724240Smckusick 
734240Smckusick 	blist[0] = -1;
744240Smckusick #ifndef STANDALONE
754240Smckusick 	while (--argc) {
764240Smckusick 		argv++;
774240Smckusick 		if (**argv=='-')
784240Smckusick 		switch ((*argv)[1]) {
794240Smckusick 		case 'd':
804240Smckusick 			dflg++;
814240Smckusick 			continue;
824240Smckusick 
834240Smckusick 		case 'm':
844240Smckusick 			mflg++;
854240Smckusick 			continue;
864240Smckusick 
87*5098Smckusic 		case 's':
88*5098Smckusic 			sflg++;
89*5098Smckusic 			continue;
90*5098Smckusic 
914240Smckusick 		case 'b':
924240Smckusick 			for(i=0; i<NB; i++) {
934240Smckusick 				n = atol(argv[1]);
944240Smckusick 				if(n == 0)
954240Smckusick 					break;
964240Smckusick 				blist[i] = n;
974240Smckusick 				argv++;
984240Smckusick 				argc--;
994240Smckusick 			}
1004240Smckusick 			blist[i] = -1;
1014240Smckusick 			continue;
1024240Smckusick 
1034240Smckusick 		default:
1044240Smckusick 			printf("Bad flag\n");
1054240Smckusick 		}
1064240Smckusick 		check(*argv);
1074240Smckusick 	}
1084240Smckusick #else
1094240Smckusick 	{
1104240Smckusick 		static char fname[128];
1114240Smckusick 
1124240Smckusick 		printf("File: ");
1134240Smckusick 		gets(fname);
1144240Smckusick 		check(fname);
1154240Smckusick 	}
1164240Smckusick #endif
1174240Smckusick 	return(nerror);
1184240Smckusick }
1194240Smckusick 
1204240Smckusick check(file)
121*5098Smckusic 	char *file;
1224240Smckusick {
1234240Smckusick 	register i, j, c;
1244240Smckusick 	daddr_t d, cgd, cbase, b;
1254240Smckusick 	long n;
1264240Smckusick 
127*5098Smckusic 	fi = open(file, sflg ? 2 : 0);
1284240Smckusick 	if (fi < 0) {
129*5098Smckusic 		perror(file);
1304240Smckusick 		nerror |= 04;
1314240Smckusick 		return;
1324240Smckusick 	}
1334240Smckusick 	printf("%s:\n", file);
1344240Smckusick 	nrfile = 0;
1354240Smckusick 	ndfile = 0;
1364240Smckusick 	ncfile = 0;
1374240Smckusick 	nbfile = 0;
1384240Smckusick 	nmcfile = 0;
1394240Smckusick 
1404240Smckusick 	nblock = 0;
1414240Smckusick 	nfrag = 0;
1424240Smckusick 	nindir = 0;
1434240Smckusick 	niindir = 0;
1444240Smckusick 
1454240Smckusick 	ndup = 0;
1464240Smckusick #ifndef STANDALONE
1474240Smckusick 	sync();
1484240Smckusick #endif
1494240Smckusick 	bread(SBLOCK, (char *)&sblock, BSIZE);
1504240Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
1514240Smckusick 		printf("%s: bad magic number\n", file);
1524240Smckusick 		nerror |= 04;
1534240Smckusick 		return;
1544240Smckusick 	}
1554654Smckusic 	for (n = 0; n < howmany(cssize(&sblock), BSIZE); n++) {
1564654Smckusic 		sblock.fs_csp[n] = (struct csum *)calloc(1, BSIZE);
1574654Smckusic 		bread(csaddr(&sblock) + (n * FRAG),
1584654Smckusic 		      (char *)sblock.fs_csp[n], BSIZE);
1594654Smckusic 	}
1604240Smckusick 	ino = 0;
161*5098Smckusic 	n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
1624240Smckusick #ifdef STANDALONE
1634240Smckusick 	bmap = NULL;
1644240Smckusick #else
1654240Smckusick 	bmap = malloc((unsigned)n);
1664240Smckusick #endif
1674240Smckusick 	if (bmap==NULL) {
1684240Smckusick 		printf("Not enough core; duplicates unchecked\n");
1694240Smckusick 		dflg++;
170*5098Smckusic 		if (sflg) {
171*5098Smckusic 			printf("No Updates\n");
172*5098Smckusic 			sflg = 0;
173*5098Smckusic 		}
1744240Smckusick 	}
1754240Smckusick 	ino = 0;
1764240Smckusick 	cginit = 1;
1774240Smckusick 	if(!dflg) {
1784240Smckusick 		for (i=0; i<(unsigned)n; i++)
1794240Smckusick 			bmap[i] = 0;
1804240Smckusick 		for (c=0; c < sblock.fs_ncg; c++) {
1814240Smckusick 			cgd = cgtod(c, &sblock);
1824410Smckusic 			for (d = cgbase(c, &sblock); d < cgd; d += FRAG)
1834429Smckusic 				chk(d, "badcg", BSIZE);
1844240Smckusick 			d = cgimin(c, &sblock);
1854240Smckusick 			while (cgd < d) {
1864429Smckusic 				chk(cgd, "cg", BSIZE);
1874410Smckusic 				cgd += FRAG;
1884240Smckusick 			}
1894240Smckusick 			d = cgdmin(c, &sblock);
1904410Smckusic 			for (; cgd < d; cgd += FRAG)
1914429Smckusic 				chk(cgd, "inode", BSIZE);
1924240Smckusick 			if (c == 0) {
1934410Smckusic 				d += howmany(cssize(&sblock), FSIZE);
1944410Smckusic 				for (; cgd < d; cgd += FRAG)
1954429Smckusic 					chk(cgd, "csum", BSIZE);
1964240Smckusick 			}
1974240Smckusick 		}
1984240Smckusick 	}
1994240Smckusick 	cginit = 0;
2004240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2014240Smckusick 		bread(cgimin(c,&sblock), (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
2124240Smckusick 	bread(SBLOCK, (char *)&sblock, sizeof(sblock));
213*5098Smckusic 	if (sflg) {
214*5098Smckusic 		makecg();
215*5098Smckusic 		close(fi);
216*5098Smckusic #ifndef STANDALONE
217*5098Smckusic 		if (bmap)
218*5098Smckusic 			free(bmap);
219*5098Smckusic #endif
220*5098Smckusic 		return;
221*5098Smckusic 	}
2224240Smckusick 	nffree = 0;
2234240Smckusick 	nbfree = 0;
2244240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2254240Smckusick 		cbase = cgbase(c,&sblock);
2264240Smckusick 		bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize);
2274240Smckusick 		for (b = 0; b < sblock.fs_fpg; b += FRAG) {
2284240Smckusick 			if (isblock(cgrp.cg_free, b / FRAG)) {
2294240Smckusick 				nbfree++;
2304429Smckusic 				chk(cbase+b, "block", BSIZE);
2314240Smckusick 			} else {
2324240Smckusick 				for (d = 0; d < FRAG; d++)
2334240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
2344429Smckusic 						chk(cbase+b+d, "frag", FSIZE);
2354240Smckusick 						nffree++;
2364240Smckusick 					}
2374240Smckusick 			}
2384240Smckusick 		}
2394240Smckusick 	}
2404240Smckusick 	close(fi);
2414240Smckusick #ifndef STANDALONE
2424240Smckusick 	if (bmap)
2434240Smckusick 		free(bmap);
2444240Smckusick #endif
2454240Smckusick 
2464240Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nmcfile;
2474240Smckusick #ifndef STANDALONE
2484240Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2494240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2504240Smckusick #else
2514240Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2524240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2534240Smckusick #endif
2544429Smckusic 	n = (nblock + nindir + niindir) * FRAG + nfrag;
2554240Smckusick #ifdef STANDALONE
2564240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2574240Smckusick 		n, nindir, niindir, nblock, nfrag);
2584429Smckusic 	printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
2594240Smckusick 	    nbfree, nffree);
2604240Smckusick #else
2614240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2624240Smckusick 		n, nindir, niindir, nblock, nfrag);
2634429Smckusic 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
2644240Smckusick 	    nbfree, nffree);
2654240Smckusick #endif
2664240Smckusick 	if(!dflg) {
2674240Smckusick 		n = 0;
2684410Smckusic 		for (d = 0; d < sblock.fs_size; d++)
2694429Smckusic 			if(!duped(d, FSIZE)) {
2704240Smckusick 				if(mflg)
2714240Smckusick 					printf("%ld missing\n", d);
2724240Smckusick 				n++;
2734240Smckusick 			}
2744240Smckusick 		printf("missing%5ld\n", n);
2754240Smckusick 	}
2764240Smckusick }
2774240Smckusick 
2784240Smckusick pass1(ip)
2794410Smckusic 	register struct dinode *ip;
2804240Smckusick {
2814429Smckusic 	daddr_t ind1[NINDIR];
2824429Smckusic 	daddr_t ind2[NINDIR];
2834429Smckusic 	daddr_t db, ib;
2844429Smckusic 	register int i, j, k, siz;
2854240Smckusick 
2864240Smckusick 	i = ip->di_mode & IFMT;
2874790Smckusic 	if(i == 0)
2884240Smckusick 		return;
2894240Smckusick 	switch (i) {
2904240Smckusick 	case IFCHR:
2914240Smckusick 		ncfile++;
2924240Smckusick 		return;
2934240Smckusick 	case IFBLK:
2944240Smckusick 		nbfile++;
2954240Smckusick 		return;
2964240Smckusick 	case IFDIR:
2974240Smckusick 		ndfile++;
2984240Smckusick 		break;
2994240Smckusick 	case IFREG:
3004240Smckusick 		nrfile++;
3014240Smckusick 		break;
3024240Smckusick 	default:
3034240Smckusick 		printf("bad mode %u\n", ino);
3044240Smckusick 		return;
3054240Smckusick 	}
3064410Smckusic 	for (i = 0; i < NDADDR; i++) {
3074410Smckusic 		db = ip->di_db[i];
3084410Smckusic 		if (db == 0)
3094240Smckusick 			continue;
3104429Smckusic 		siz = dblksize(ip, i);
3114429Smckusic 		chk(db, "data (block)", siz);
3124429Smckusic 		if (siz == BSIZE)
3134429Smckusic 			nblock++;
3144429Smckusic 		else
3154429Smckusic 			nfrag += howmany(siz, FSIZE);
3164240Smckusick 	}
3174410Smckusic 	for(i = 0; i < NIADDR; i++) {
3184410Smckusic 		ib = ip->di_ib[i];
3194410Smckusic 		if(ib == 0)
3204240Smckusick 			continue;
3214429Smckusic 		if (chk(ib, "1st indirect", BSIZE))
3224410Smckusic 			continue;
3234429Smckusic 		bread(ib, (char *)ind1, BSIZE);
3244240Smckusick 		nindir++;
3254410Smckusic 		for (j = 0; j < NINDIR; j++) {
3264410Smckusic 			ib = ind1[j];
3274410Smckusic 			if (ib == 0)
3284240Smckusick 				continue;
3294410Smckusic 			if (i == 0) {
3304429Smckusic 				siz = dblksize(ip, NDADDR + j);
3314429Smckusic 				chk(ib, "data (large)", siz);
3324429Smckusic 				if (siz == BSIZE)
3334429Smckusic 					nblock++;
3344429Smckusic 				else
3354429Smckusic 					nfrag += howmany(siz, FSIZE);
3364240Smckusick 				continue;
3374240Smckusick 			}
3384429Smckusic 			if (chk(ib, "2nd indirect", BSIZE))
3394410Smckusic 				continue;
3404429Smckusic 			bread(ib, (char *)ind2, BSIZE);
3414240Smckusick 			niindir++;
3424410Smckusic 			for (k = 0; k < NINDIR; k++) {
3434410Smckusic 				ib = ind2[k];
3444410Smckusic 				if (ib == 0)
3454240Smckusick 					continue;
3464429Smckusic 				siz = dblksize(ip,
3474429Smckusic 				    NDADDR + NINDIR * (i + j) + k);
3484429Smckusic 				chk(ib, "data (huge)", siz);
3494429Smckusic 				if (siz == BSIZE)
3504429Smckusic 					nblock++;
3514429Smckusic 				else
3524429Smckusic 					nfrag += howmany(siz, FSIZE);
3534240Smckusick 			}
3544240Smckusick 		}
3554240Smckusick 	}
3564240Smckusick }
3574240Smckusick 
3584429Smckusic chk(bno, s, size)
3594410Smckusic 	daddr_t bno;
3604410Smckusic 	char *s;
3614429Smckusic 	int size;
3624240Smckusick {
3634240Smckusick 	register n, cg;
3644240Smckusick 
3654240Smckusick 	cg = dtog(bno, &sblock);
3664429Smckusic 	if (cginit==0 &&
3674429Smckusic 	    bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) {
3684240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
3694240Smckusick 		return(1);
3704240Smckusick 	}
3714429Smckusic 	if (size == BSIZE) {
3724429Smckusic 		if (duped(bno, size)) {
3734429Smckusic 			printf("%ld dup block; inode=%u, class=%s\n",
3744429Smckusic 			    bno, ino, s);
3754429Smckusic 			ndup += FRAG;
3764429Smckusic 		}
3774429Smckusic 	} else {
3784429Smckusic 		for (n = 0; n < size / FSIZE; n++) {
3794429Smckusic 			if (duped(bno + n, FSIZE)) {
3804429Smckusic 				printf("%ld dup frag; inode=%u, class=%s\n",
3814429Smckusic 				    bno, ino, s);
3824429Smckusic 				ndup++;
3834429Smckusic 			}
3844429Smckusic 		}
3854240Smckusick 	}
3864240Smckusick 	for (n=0; blist[n] != -1; n++)
3874240Smckusick 		if (bno == blist[n])
3884240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
3894240Smckusick 	return(0);
3904240Smckusick }
3914240Smckusick 
3924429Smckusic duped(bno, size)
3934410Smckusic 	daddr_t bno;
3944429Smckusic 	int size;
3954240Smckusick {
3964240Smckusick 	if(dflg)
3974240Smckusick 		return(0);
3984429Smckusic 	if (size != FSIZE && size != BSIZE)
3994429Smckusic 		printf("bad size %d to duped\n", size);
4004429Smckusic 	if (size == FSIZE) {
4014410Smckusic 		if (isset(bmap, bno))
4024410Smckusic 			return(1);
4034410Smckusic 		setbit(bmap, bno);
4044410Smckusic 		return (0);
4054410Smckusic 	}
4064410Smckusic 	if (bno % FRAG != 0)
4074410Smckusic 		printf("bad bno %d to duped\n", bno);
4084410Smckusic 	if (isblock(bmap, bno/FRAG))
4094410Smckusic 		return (1);
4104410Smckusic 	setblock(bmap, bno/FRAG);
4114240Smckusick 	return(0);
4124240Smckusick }
4134240Smckusick 
414*5098Smckusic makecg()
415*5098Smckusic {
416*5098Smckusic 	int c, blk;
417*5098Smckusic 	daddr_t dbase, d, dmin, dmax;
418*5098Smckusic 	long i, j, s;
419*5098Smckusic 	register struct csum *cs;
420*5098Smckusic 	register struct dinode *dp;
421*5098Smckusic 
422*5098Smckusic 	sblock.fs_cstotal.cs_nbfree = 0;
423*5098Smckusic 	sblock.fs_cstotal.cs_nffree = 0;
424*5098Smckusic 	sblock.fs_cstotal.cs_nifree = 0;
425*5098Smckusic 	sblock.fs_cstotal.cs_ndir = 0;
426*5098Smckusic 	for (i = 0; i < howmany(cssize(&sblock), BSIZE); i++) {
427*5098Smckusic 		sblock.fs_csp[i] = (struct csum *)calloc(1, BSIZE);
428*5098Smckusic 		bread(csaddr(&sblock) + (i * FRAG),
429*5098Smckusic 		      (char *)sblock.fs_csp[i], BSIZE);
430*5098Smckusic 	}
431*5098Smckusic 	for (c = 0; c < sblock.fs_ncg; c++) {
432*5098Smckusic 		dbase = cgbase(c, &sblock);
433*5098Smckusic 		dmax = dbase + sblock.fs_fpg;
434*5098Smckusic 		if (dmax > sblock.fs_size)
435*5098Smckusic 			dmax = sblock.fs_size;
436*5098Smckusic 		dmin = cgdmin(c, &sblock) - dbase;
437*5098Smckusic 		cs = &sblock.fs_cs(c);
438*5098Smckusic 		cgrp.cg_time = time(0);
439*5098Smckusic 		cgrp.cg_magic = CG_MAGIC;
440*5098Smckusic 		cgrp.cg_cgx = c;
441*5098Smckusic 		cgrp.cg_ncyl = sblock.fs_cpg;
442*5098Smckusic 		cgrp.cg_niblk = sblock.fs_ipg;
443*5098Smckusic 		cgrp.cg_ndblk = dmax - dbase;
444*5098Smckusic 		cgrp.cg_cs.cs_ndir = 0;
445*5098Smckusic 		cgrp.cg_cs.cs_nffree = 0;
446*5098Smckusic 		cgrp.cg_cs.cs_nbfree = 0;
447*5098Smckusic 		cgrp.cg_cs.cs_nifree = 0;
448*5098Smckusic 		cgrp.cg_rotor = dmin;
449*5098Smckusic 		cgrp.cg_frotor = dmin;
450*5098Smckusic 		cgrp.cg_irotor = 0;
451*5098Smckusic 		for (i = 0; i < FRAG; i++)
452*5098Smckusic 			cgrp.cg_frsum[i] = 0;
453*5098Smckusic 		bread(cgimin(c, &sblock), (char *)itab,
454*5098Smckusic 		      sblock.fs_ipg * sizeof(struct dinode));
455*5098Smckusic 		for (i = 0; i < sblock.fs_ipg; i++) {
456*5098Smckusic 			dp = &itab[i];
457*5098Smckusic 			if (dp == NULL)
458*5098Smckusic 				continue;
459*5098Smckusic 			if ((dp->di_mode & IFMT) != 0) {
460*5098Smckusic 				if ((dp->di_mode & IFMT) == IFDIR)
461*5098Smckusic 					cgrp.cg_cs.cs_ndir++;
462*5098Smckusic 				setbit(cgrp.cg_iused, i);
463*5098Smckusic 				continue;
464*5098Smckusic 			}
465*5098Smckusic 			cgrp.cg_cs.cs_nifree++;
466*5098Smckusic 			clrbit(cgrp.cg_iused, i);
467*5098Smckusic 		}
468*5098Smckusic 		while (i < MAXIPG) {
469*5098Smckusic 			clrbit(cgrp.cg_iused, i);
470*5098Smckusic 			i++;
471*5098Smckusic 		}
472*5098Smckusic 		for (s = 0; s < MAXCPG; s++)
473*5098Smckusic 			for (i = 0; i < NRPOS; i++)
474*5098Smckusic 				cgrp.cg_b[s][i] = 0;
475*5098Smckusic 		if (c == 0) {
476*5098Smckusic 			dmin += howmany(cssize(&sblock), BSIZE) * FRAG;
477*5098Smckusic 		}
478*5098Smckusic 		for (d = 0; d < dmin; d++)
479*5098Smckusic 			clrbit(cgrp.cg_free, d);
480*5098Smckusic 		for (; (d + FRAG) <= dmax - dbase; d += FRAG) {
481*5098Smckusic 			j = 0;
482*5098Smckusic 			for (i = 0; i < FRAG; i++) {
483*5098Smckusic 				if (!isset(bmap, dbase+d+i)) {
484*5098Smckusic 					setbit(cgrp.cg_free, d+i);
485*5098Smckusic 					j++;
486*5098Smckusic 				} else
487*5098Smckusic 					clrbit(cgrp.cg_free, d+i);
488*5098Smckusic 			}
489*5098Smckusic 			if (j == FRAG) {
490*5098Smckusic 				cgrp.cg_cs.cs_nbfree++;
491*5098Smckusic 				s = d * NSPF;
492*5098Smckusic 				cgrp.cg_b[s/sblock.fs_spc]
493*5098Smckusic 				  [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++;
494*5098Smckusic 			} else if (j > 0) {
495*5098Smckusic 				cgrp.cg_cs.cs_nffree += j;
496*5098Smckusic 				blk = ((cgrp.cg_free[d / NBBY] >> (d % NBBY)) &
497*5098Smckusic 				       (0xff >> (NBBY - FRAG)));
498*5098Smckusic 				fragacct(blk, cgrp.cg_frsum, 1);
499*5098Smckusic 			}
500*5098Smckusic 		}
501*5098Smckusic 		for (j = d; d < dmax - dbase; d++) {
502*5098Smckusic 			if (!isset(bmap, dbase+d)) {
503*5098Smckusic 				setbit(cgrp.cg_free, d);
504*5098Smckusic 				cgrp.cg_cs.cs_nffree++;
505*5098Smckusic 			} else
506*5098Smckusic 				clrbit(cgrp.cg_free, d);
507*5098Smckusic 		}
508*5098Smckusic 		if (j != d) {
509*5098Smckusic 			blk = ((cgrp.cg_free[j / NBBY] >> (j % NBBY)) &
510*5098Smckusic 			       (0xff >> (NBBY - FRAG)));
511*5098Smckusic 			fragacct(blk, cgrp.cg_frsum, 1);
512*5098Smckusic 		}
513*5098Smckusic 		for (; d < MAXBPG; d++)
514*5098Smckusic 			clrbit(cgrp.cg_free, d);
515*5098Smckusic 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
516*5098Smckusic 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
517*5098Smckusic 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
518*5098Smckusic 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
519*5098Smckusic 		*cs = cgrp.cg_cs;
520*5098Smckusic 		bwrite(cgtod(c, &sblock), &cgrp, sblock.fs_cgsize);
521*5098Smckusic 	}
522*5098Smckusic 	for (i = 0; i < howmany(cssize(&sblock), BSIZE); i++) {
523*5098Smckusic 		bwrite(csaddr(&sblock) + (i * FRAG),
524*5098Smckusic 		       (char *)sblock.fs_csp[i], BSIZE);
525*5098Smckusic 	}
526*5098Smckusic 	sblock.fs_ronly = 0;
527*5098Smckusic 	sblock.fs_fmod = 0;
528*5098Smckusic 	bwrite(SBLOCK, (char *)&sblock, sizeof(sblock));
529*5098Smckusic }
530*5098Smckusic 
531*5098Smckusic /*
532*5098Smckusic  * update the frsum fields to reflect addition or deletion
533*5098Smckusic  * of some frags
534*5098Smckusic  */
535*5098Smckusic fragacct(fragmap, fraglist, cnt)
536*5098Smckusic 	int fragmap;
537*5098Smckusic 	long fraglist[];
538*5098Smckusic 	int cnt;
539*5098Smckusic {
540*5098Smckusic 	int inblk;
541*5098Smckusic 	register int field, subfield;
542*5098Smckusic 	register int siz, pos;
543*5098Smckusic 
544*5098Smckusic 	inblk = (int)(fragtbl[fragmap] << 1);
545*5098Smckusic 	fragmap <<= 1;
546*5098Smckusic 	for (siz = 1; siz < FRAG; siz++) {
547*5098Smckusic 		if (((1 << siz) & inblk) == 0)
548*5098Smckusic 			continue;
549*5098Smckusic 		field = around[siz];
550*5098Smckusic 		subfield = inside[siz];
551*5098Smckusic 		for (pos = siz; pos <= FRAG; pos++) {
552*5098Smckusic 			if ((fragmap & field) == subfield) {
553*5098Smckusic 				fraglist[siz] += cnt;
554*5098Smckusic 				pos += siz;
555*5098Smckusic 				field <<= siz;
556*5098Smckusic 				subfield <<= siz;
557*5098Smckusic 			}
558*5098Smckusic 			field <<= 1;
559*5098Smckusic 			subfield <<= 1;
560*5098Smckusic 		}
561*5098Smckusic 	}
562*5098Smckusic }
563*5098Smckusic 
564*5098Smckusic bwrite(blk, buf, size)
565*5098Smckusic 	char *buf;
566*5098Smckusic 	daddr_t blk;
567*5098Smckusic 	register size;
568*5098Smckusic {
569*5098Smckusic 	if (lseek(fi, blk * FSIZE, 0) < 0) {
570*5098Smckusic 		perror("FS SEEK");
571*5098Smckusic 		return(1);
572*5098Smckusic 	}
573*5098Smckusic 	if (write(fi, buf, size) != size) {
574*5098Smckusic 		perror("FS WRITE");
575*5098Smckusic 		return(1);
576*5098Smckusic 	}
577*5098Smckusic }
578*5098Smckusic 
5794240Smckusick bread(bno, buf, cnt)
5804410Smckusic 	daddr_t bno;
5814410Smckusic 	char *buf;
5824240Smckusick {
5834240Smckusick 	register i;
5844240Smckusick 
585*5098Smckusic 	lseek(fi, bno * FSIZE, 0);
5864240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
587*5098Smckusic 		if (sflg) {
588*5098Smckusic 			printf("No Update\n");
589*5098Smckusic 			sflg = 0;
590*5098Smckusic 		}
5914240Smckusick 		for(i=0; i<BSIZE; i++)
5924240Smckusick 			buf[i] = 0;
5934240Smckusick 	}
5944240Smckusick }
595