xref: /csrg-svn/sbin/icheck/icheck.c (revision 4429)
1*4429Smckusic static	char *sccsid = "@(#)icheck.c	1.5 (Berkeley) 09/22/81";
24410Smckusic 
34240Smckusick /*
44240Smckusick  * icheck
54240Smckusick  */
64240Smckusick #define	NB	500
74240Smckusick #define	BITS	8
84240Smckusick #define	MAXFN	500
94240Smckusick 
104240Smckusick #ifndef STANDALONE
114240Smckusick #include <stdio.h>
124240Smckusick #endif
134240Smckusick #include "../h/param.h"
144240Smckusick #include "../h/inode.h"
154240Smckusick #include "../h/fs.h"
164240Smckusick 
174240Smckusick union {
184240Smckusick 	struct	fs sb;
194240Smckusick 	char pad[BSIZE];
204240Smckusick } sbun;
214240Smckusick #define	sblock sbun.sb
224240Smckusick 
234240Smckusick union {
244240Smckusick 	struct	cg cg;
254240Smckusick 	char pad[BSIZE];
264240Smckusick } cgun;
274240Smckusick #define	cgrp cgun.cg
284240Smckusick 
294240Smckusick struct	dinode	itab[MAXIPG];
304240Smckusick daddr_t	blist[NB];
314240Smckusick char	*bmap;
324240Smckusick 
334240Smckusick int	sflg;
344240Smckusick int	mflg;
354240Smckusick int	dflg;
364240Smckusick int	fi;
374240Smckusick ino_t	ino;
384240Smckusick int	cginit;
394240Smckusick 
404240Smckusick ino_t	nrfile;
414240Smckusick ino_t	ndfile;
424240Smckusick ino_t	nbfile;
434240Smckusick ino_t	ncfile;
444240Smckusick ino_t	nmcfile;
454240Smckusick 
464240Smckusick daddr_t	nblock;
474240Smckusick daddr_t	nfrag;
484240Smckusick daddr_t	nindir;
494240Smckusick daddr_t	niindir;
504240Smckusick 
514240Smckusick daddr_t	nffree;
524240Smckusick daddr_t	nbfree;
534240Smckusick 
544240Smckusick daddr_t	ndup;
554240Smckusick 
564240Smckusick int	nerror;
574240Smckusick 
584240Smckusick long	atol();
594240Smckusick daddr_t	alloc();
604240Smckusick #ifndef STANDALONE
614240Smckusick char	*malloc();
624240Smckusick #endif
634240Smckusick 
644240Smckusick main(argc, argv)
654240Smckusick char *argv[];
664240Smckusick {
674240Smckusick 	register i;
684240Smckusick 	long n;
694240Smckusick 
704240Smckusick 	blist[0] = -1;
714240Smckusick #ifndef STANDALONE
724240Smckusick 	while (--argc) {
734240Smckusick 		argv++;
744240Smckusick 		if (**argv=='-')
754240Smckusick 		switch ((*argv)[1]) {
764240Smckusick 		case 'd':
774240Smckusick 			dflg++;
784240Smckusick 			continue;
794240Smckusick 
804240Smckusick 		case 'm':
814240Smckusick 			mflg++;
824240Smckusick 			continue;
834240Smckusick 
844240Smckusick 		case 's':
854240Smckusick 			sflg++;
864240Smckusick 			continue;
874240Smckusick 
884240Smckusick 		case 'b':
894240Smckusick 			for(i=0; i<NB; i++) {
904240Smckusick 				n = atol(argv[1]);
914240Smckusick 				if(n == 0)
924240Smckusick 					break;
934240Smckusick 				blist[i] = n;
944240Smckusick 				argv++;
954240Smckusick 				argc--;
964240Smckusick 			}
974240Smckusick 			blist[i] = -1;
984240Smckusick 			continue;
994240Smckusick 
1004240Smckusick 		default:
1014240Smckusick 			printf("Bad flag\n");
1024240Smckusick 		}
1034240Smckusick 		check(*argv);
1044240Smckusick 	}
1054240Smckusick #else
1064240Smckusick 	{
1074240Smckusick 		static char fname[128];
1084240Smckusick 
1094240Smckusick 		printf("File: ");
1104240Smckusick 		gets(fname);
1114240Smckusick 		check(fname);
1124240Smckusick 	}
1134240Smckusick #endif
1144240Smckusick 	return(nerror);
1154240Smckusick }
1164240Smckusick 
1174240Smckusick check(file)
1184240Smckusick char *file;
1194240Smckusick {
1204240Smckusick 	register i, j, c;
1214240Smckusick 	daddr_t d, cgd, cbase, b;
1224240Smckusick 	long n;
1234240Smckusick 
1244240Smckusick 	fi = open(file, sflg?2:0);
1254240Smckusick 	if (fi < 0) {
1264240Smckusick 		printf("cannot open %s\n", file);
1274240Smckusick 		nerror |= 04;
1284240Smckusick 		return;
1294240Smckusick 	}
1304240Smckusick 	printf("%s:\n", file);
1314240Smckusick 	nrfile = 0;
1324240Smckusick 	ndfile = 0;
1334240Smckusick 	ncfile = 0;
1344240Smckusick 	nbfile = 0;
1354240Smckusick 	nmcfile = 0;
1364240Smckusick 
1374240Smckusick 	nblock = 0;
1384240Smckusick 	nfrag = 0;
1394240Smckusick 	nindir = 0;
1404240Smckusick 	niindir = 0;
1414240Smckusick 
1424240Smckusick 	ndup = 0;
1434240Smckusick #ifndef STANDALONE
1444240Smckusick 	sync();
1454240Smckusick #endif
1464240Smckusick 	bread(SBLOCK, (char *)&sblock, BSIZE);
1474240Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
1484240Smckusick 		printf("%s: bad magic number\n", file);
1494240Smckusick 		nerror |= 04;
1504240Smckusick 		return;
1514240Smckusick 	}
1524240Smckusick 	sblock.fs_cs =
1534240Smckusick 	    (struct csum *)calloc(howmany(cssize(&sblock), BSIZE), BSIZE);
1544240Smckusick 	lseek(fi, csaddr(&sblock)*FSIZE, 0);
1554240Smckusick 	read(fi, (char *)sblock.fs_cs, cssize(&sblock));
1564240Smckusick 	ino = 0;
1574240Smckusick 	n = (sblock.fs_size*FRAG + BITS-1) / BITS;
1584240Smckusick #ifdef STANDALONE
1594240Smckusick 	bmap = NULL;
1604240Smckusick #else
1614240Smckusick 	bmap = malloc((unsigned)n);
1624240Smckusick #endif
1634240Smckusick 	if (bmap==NULL) {
1644240Smckusick 		printf("Not enough core; duplicates unchecked\n");
1654240Smckusick 		dflg++;
1664240Smckusick 		sflg = 0;
1674240Smckusick 	}
1684240Smckusick 	ino = 0;
1694240Smckusick 	cginit = 1;
1704240Smckusick 	if(!dflg) {
1714240Smckusick 		for (i=0; i<(unsigned)n; i++)
1724240Smckusick 			bmap[i] = 0;
1734240Smckusick 		for (c=0; c < sblock.fs_ncg; c++) {
1744240Smckusick 			cgd = cgtod(c, &sblock);
1754410Smckusic 			for (d = cgbase(c, &sblock); d < cgd; d += FRAG)
176*4429Smckusic 				chk(d, "badcg", BSIZE);
1774240Smckusick 			d = cgimin(c, &sblock);
1784240Smckusick 			while (cgd < d) {
179*4429Smckusic 				chk(cgd, "cg", BSIZE);
1804410Smckusic 				cgd += FRAG;
1814240Smckusick 			}
1824240Smckusick 			d = cgdmin(c, &sblock);
1834410Smckusic 			for (; cgd < d; cgd += FRAG)
184*4429Smckusic 				chk(cgd, "inode", BSIZE);
1854240Smckusick 			if (c == 0) {
1864410Smckusic 				d += howmany(cssize(&sblock), FSIZE);
1874410Smckusic 				for (; cgd < d; cgd += FRAG)
188*4429Smckusic 					chk(cgd, "csum", BSIZE);
1894240Smckusick 			}
1904240Smckusick 		}
1914240Smckusick 	}
1924240Smckusick 	cginit = 0;
1934240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1944240Smckusick 		bread(cgimin(c,&sblock), (char *)itab,
1954240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1964240Smckusick 		for (j=0; j < sblock.fs_ipg; j++) {
1974240Smckusick 			pass1(&itab[j]);
1984240Smckusick 			ino++;
1994240Smckusick 		}
2004240Smckusick 	}
2014240Smckusick 	ino = 0;
2024240Smckusick #ifndef STANDALONE
2034240Smckusick 	sync();
2044240Smckusick #endif
2054240Smckusick 	bread(SBLOCK, (char *)&sblock, sizeof(sblock));
2064240Smckusick 	if (sflg) {
2074240Smckusick 		makecg();
2084240Smckusick 		close(fi);
2094240Smckusick #ifndef STANDALONE
2104240Smckusick 		if (bmap)
2114240Smckusick 			free(bmap);
2124240Smckusick #endif
2134240Smckusick 		return;
2144240Smckusick 	}
2154240Smckusick 	nffree = 0;
2164240Smckusick 	nbfree = 0;
2174240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2184240Smckusick 		cbase = cgbase(c,&sblock);
2194240Smckusick 		bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize);
2204240Smckusick 		for (b = 0; b < sblock.fs_fpg; b += FRAG) {
2214240Smckusick 			if (isblock(cgrp.cg_free, b / FRAG)) {
2224240Smckusick 				nbfree++;
223*4429Smckusic 				chk(cbase+b, "block", BSIZE);
2244240Smckusick 			} else {
2254240Smckusick 				for (d = 0; d < FRAG; d++)
2264240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
227*4429Smckusic 						chk(cbase+b+d, "frag", FSIZE);
2284240Smckusick 						nffree++;
2294240Smckusick 					}
2304240Smckusick 			}
2314240Smckusick 		}
2324240Smckusick 	}
2334240Smckusick 	close(fi);
2344240Smckusick #ifndef STANDALONE
2354240Smckusick 	if (bmap)
2364240Smckusick 		free(bmap);
2374240Smckusick #endif
2384240Smckusick 
2394240Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nmcfile;
2404240Smckusick #ifndef STANDALONE
2414240Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2424240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2434240Smckusick #else
2444240Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2454240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2464240Smckusick #endif
247*4429Smckusic 	n = (nblock + nindir + niindir) * FRAG + nfrag;
2484240Smckusick #ifdef STANDALONE
2494240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2504240Smckusick 		n, nindir, niindir, nblock, nfrag);
251*4429Smckusic 	printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
2524240Smckusick 	    nbfree, nffree);
2534240Smckusick #else
2544240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2554240Smckusick 		n, nindir, niindir, nblock, nfrag);
256*4429Smckusic 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
2574240Smckusick 	    nbfree, nffree);
2584240Smckusick #endif
2594240Smckusick 	if(!dflg) {
2604240Smckusick 		n = 0;
2614410Smckusic 		for (d = 0; d < sblock.fs_size; d++)
262*4429Smckusic 			if(!duped(d, FSIZE)) {
2634240Smckusick 				if(mflg)
2644240Smckusick 					printf("%ld missing\n", d);
2654240Smckusick 				n++;
2664240Smckusick 			}
2674240Smckusick 		printf("missing%5ld\n", n);
2684240Smckusick 	}
2694240Smckusick }
2704240Smckusick 
2714240Smckusick pass1(ip)
2724410Smckusic 	register struct dinode *ip;
2734240Smckusick {
274*4429Smckusic 	daddr_t ind1[NINDIR];
275*4429Smckusic 	daddr_t ind2[NINDIR];
276*4429Smckusic 	daddr_t db, ib;
277*4429Smckusic 	register int i, j, k, siz;
2784240Smckusick 
2794240Smckusick 	i = ip->di_mode & IFMT;
2804240Smckusick 	if(i == 0) {
2814240Smckusick 		sblock.fs_nifree++;
2824240Smckusick 		return;
2834240Smckusick 	}
2844240Smckusick 	switch (i) {
2854240Smckusick 	case IFCHR:
2864240Smckusick 		ncfile++;
2874240Smckusick 		return;
2884240Smckusick 	case IFBLK:
2894240Smckusick 		nbfile++;
2904240Smckusick 		return;
2914240Smckusick 	case IFDIR:
2924240Smckusick 		ndfile++;
2934240Smckusick 		break;
2944240Smckusick 	case IFREG:
2954240Smckusick 		nrfile++;
2964240Smckusick 		break;
2974240Smckusick 	default:
2984240Smckusick 		printf("bad mode %u\n", ino);
2994240Smckusick 		return;
3004240Smckusick 	}
3014410Smckusic 	for (i = 0; i < NDADDR; i++) {
3024410Smckusic 		db = ip->di_db[i];
3034410Smckusic 		if (db == 0)
3044240Smckusick 			continue;
305*4429Smckusic 		siz = dblksize(ip, i);
306*4429Smckusic 		chk(db, "data (block)", siz);
307*4429Smckusic 		if (siz == BSIZE)
308*4429Smckusic 			nblock++;
309*4429Smckusic 		else
310*4429Smckusic 			nfrag += howmany(siz, FSIZE);
3114240Smckusick 	}
3124410Smckusic 	for(i = 0; i < NIADDR; i++) {
3134410Smckusic 		ib = ip->di_ib[i];
3144410Smckusic 		if(ib == 0)
3154240Smckusick 			continue;
316*4429Smckusic 		if (chk(ib, "1st indirect", BSIZE))
3174410Smckusic 			continue;
318*4429Smckusic 		bread(ib, (char *)ind1, BSIZE);
3194240Smckusick 		nindir++;
3204410Smckusic 		for (j = 0; j < NINDIR; j++) {
3214410Smckusic 			ib = ind1[j];
3224410Smckusic 			if (ib == 0)
3234240Smckusick 				continue;
3244410Smckusic 			if (i == 0) {
325*4429Smckusic 				siz = dblksize(ip, NDADDR + j);
326*4429Smckusic 				chk(ib, "data (large)", siz);
327*4429Smckusic 				if (siz == BSIZE)
328*4429Smckusic 					nblock++;
329*4429Smckusic 				else
330*4429Smckusic 					nfrag += howmany(siz, FSIZE);
3314240Smckusick 				continue;
3324240Smckusick 			}
333*4429Smckusic 			if (chk(ib, "2nd indirect", BSIZE))
3344410Smckusic 				continue;
335*4429Smckusic 			bread(ib, (char *)ind2, BSIZE);
3364240Smckusick 			niindir++;
3374410Smckusic 			for (k = 0; k < NINDIR; k++) {
3384410Smckusic 				ib = ind2[k];
3394410Smckusic 				if (ib == 0)
3404240Smckusick 					continue;
341*4429Smckusic 				siz = dblksize(ip,
342*4429Smckusic 				    NDADDR + NINDIR * (i + j) + k);
343*4429Smckusic 				chk(ib, "data (huge)", siz);
344*4429Smckusic 				if (siz == BSIZE)
345*4429Smckusic 					nblock++;
346*4429Smckusic 				else
347*4429Smckusic 					nfrag += howmany(siz, FSIZE);
3484240Smckusick 			}
3494240Smckusick 		}
3504240Smckusick 	}
3514240Smckusick }
3524240Smckusick 
353*4429Smckusic chk(bno, s, size)
3544410Smckusic 	daddr_t bno;
3554410Smckusic 	char *s;
356*4429Smckusic 	int size;
3574240Smckusick {
3584240Smckusick 	register n, cg;
3594240Smckusick 
3604240Smckusick 	cg = dtog(bno, &sblock);
361*4429Smckusic 	if (cginit==0 &&
362*4429Smckusic 	    bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) {
3634240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
3644240Smckusick 		return(1);
3654240Smckusick 	}
366*4429Smckusic 	if (size == BSIZE) {
367*4429Smckusic 		if (duped(bno, size)) {
368*4429Smckusic 			printf("%ld dup block; inode=%u, class=%s\n",
369*4429Smckusic 			    bno, ino, s);
370*4429Smckusic 			ndup += FRAG;
371*4429Smckusic 		}
372*4429Smckusic 	} else {
373*4429Smckusic 		for (n = 0; n < size / FSIZE; n++) {
374*4429Smckusic 			if (duped(bno + n, FSIZE)) {
375*4429Smckusic 				printf("%ld dup frag; inode=%u, class=%s\n",
376*4429Smckusic 				    bno, ino, s);
377*4429Smckusic 				ndup++;
378*4429Smckusic 			}
379*4429Smckusic 		}
3804240Smckusick 	}
3814240Smckusick 	for (n=0; blist[n] != -1; n++)
3824240Smckusick 		if (bno == blist[n])
3834240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
3844240Smckusick 	return(0);
3854240Smckusick }
3864240Smckusick 
387*4429Smckusic duped(bno, size)
3884410Smckusic 	daddr_t bno;
389*4429Smckusic 	int size;
3904240Smckusick {
3914240Smckusick 	if(dflg)
3924240Smckusick 		return(0);
393*4429Smckusic 	if (size != FSIZE && size != BSIZE)
394*4429Smckusic 		printf("bad size %d to duped\n", size);
395*4429Smckusic 	if (size == FSIZE) {
3964410Smckusic 		if (isset(bmap, bno))
3974410Smckusic 			return(1);
3984410Smckusic 		setbit(bmap, bno);
3994410Smckusic 		return (0);
4004410Smckusic 	}
4014410Smckusic 	if (bno % FRAG != 0)
4024410Smckusic 		printf("bad bno %d to duped\n", bno);
4034410Smckusic 	if (isblock(bmap, bno/FRAG))
4044410Smckusic 		return (1);
4054410Smckusic 	setblock(bmap, bno/FRAG);
4064240Smckusick 	return(0);
4074240Smckusick }
4084240Smckusick 
4094240Smckusick bread(bno, buf, cnt)
4104410Smckusic 	daddr_t bno;
4114410Smckusic 	char *buf;
4124240Smckusick {
4134240Smckusick 	register i;
4144240Smckusick 
4154240Smckusick 	lseek(fi, bno*FSIZE, 0);
4164240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
4174240Smckusick 		if (sflg) {
4184240Smckusick 			printf("No update\n");
4194240Smckusick 			sflg = 0;
4204240Smckusick 		}
4214240Smckusick 		for(i=0; i<BSIZE; i++)
4224240Smckusick 			buf[i] = 0;
4234240Smckusick 	}
4244240Smckusick }
4254240Smckusick 
4264240Smckusick bwrite(bno, buf, cnt)
4274410Smckusic 	daddr_t bno;
4284410Smckusic 	char *buf;
4294240Smckusick {
4304240Smckusick 	lseek(fi, bno*FSIZE, 0);
4314240Smckusick 	if (write(fi, buf, cnt) != cnt)
4324240Smckusick 		printf("write error %d\n", tell(fi)/BSIZE);
4334240Smckusick }
4344240Smckusick 
4354240Smckusick makecg()
4364240Smckusick {
4374240Smckusick 	int c;
4384240Smckusick 	daddr_t dbase, d, dmin, dmax;
4394240Smckusick 	long i, j, s;
4404240Smckusick 	register struct csum *cs;
4414240Smckusick 
4424240Smckusick 	sblock.fs_nbfree = 0;
4434240Smckusick 	sblock.fs_nffree = 0;
4444240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
4454240Smckusick 		bread(cgimin(c,&sblock), (char *)itab,
4464240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
4474240Smckusick 		dbase = cgbase(c, &sblock);
4484240Smckusick 		dmax = dbase + sblock.fs_fpg;
4494240Smckusick 		if (dmax > sblock.fs_size)
4504240Smckusick 			dmax = sblock.fs_size;
4514240Smckusick 		cs = &sblock.fs_cs[c];
4524410Smckusic 		cgrp.cg_time = time((long)0);
4534240Smckusick 		cgrp.cg_magic = CG_MAGIC;
4544240Smckusick 		cgrp.cg_cgx = c;
4554240Smckusick 		cgrp.cg_ncyl = sblock.fs_cpg;
4564240Smckusick 		cgrp.cg_niblk = sblock.fs_ipg;
4574240Smckusick 		cgrp.cg_ndblk = dmax - dbase;
4584240Smckusick 		cgrp.cg_ndir = 0;
4594240Smckusick 		cgrp.cg_nffree = 0;
4604240Smckusick 		cgrp.cg_nbfree = 0;
4614240Smckusick 		cgrp.cg_nifree = 0;
4624240Smckusick 		for (i = 0; i < sblock.fs_ipg; i++)
4634240Smckusick 		switch (itab[i].di_mode&IFMT) {
4644240Smckusick 
4654240Smckusick 		case 0:
4664240Smckusick 			cgrp.cg_nifree++;
4674240Smckusick 			clrbit(cgrp.cg_iused, i);
4684240Smckusick 			continue;
4694240Smckusick 
4704240Smckusick 		case IFDIR:
4714240Smckusick 			cgrp.cg_ndir++;
4724240Smckusick 			/* fall into ... */
4734240Smckusick 
4744240Smckusick 		default:
4754240Smckusick 			setbit(cgrp.cg_iused, i);
4764240Smckusick 			continue;
4774240Smckusick 		}
4784240Smckusick 		while (i < MAXIPG) {
4794240Smckusick 			clrbit(cgrp.cg_iused, i);
4804240Smckusick 			i++;
4814240Smckusick 		}
4824240Smckusick 		for (s = 0; s < MAXCPG; s++)
4834240Smckusick 			for (i = 0; i < NRPOS; i++)
4844240Smckusick 				cgrp.cg_b[s][i] = 0;
4854240Smckusick 		dmin = cgdmin(c, &sblock) - dbase;
4864240Smckusick 		if (c == 0)
4874240Smckusick 			dmin += howmany(cssize(&sblock), BSIZE) * FRAG;
4884240Smckusick 		for (d = 0; d < dmin; d++)
4894240Smckusick 			clrbit(cgrp.cg_free, d);
4904240Smckusick #define	getbmap(i) isset(bmap, i)
4914240Smckusick 		for (; (d + FRAG) <= dmax - dbase; d += FRAG) {
4924240Smckusick 			j = 0;
4934240Smckusick 			for (i = 0; i < FRAG; i++) {
4944240Smckusick 				if (!getbmap(dbase+d+i)) {
4954240Smckusick 					setbit(cgrp.cg_free, d+i);
4964240Smckusick 					j++;
4974240Smckusick 				} else
4984240Smckusick 					clrbit(cgrp.cg_free, d+i);
4994240Smckusick 			}
5004240Smckusick 			if (j == FRAG) {
5014240Smckusick 				cgrp.cg_nbfree++;
5024240Smckusick 				s = d * NSPF;
5034240Smckusick 				cgrp.cg_b[s/sblock.fs_spc]
5044240Smckusick 				  [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++;
5054240Smckusick 			} else
5064240Smckusick 				cgrp.cg_nffree += j;
5074240Smckusick 		}
5084240Smckusick 		for (; d < dmax - dbase; d++) {
5094240Smckusick 			if (!getbmap(dbase+d)) {
5104240Smckusick 				setbit(cgrp.cg_free, d);
5114240Smckusick 				cgrp.cg_nffree++;
5124240Smckusick 			} else
5134240Smckusick 				clrbit(cgrp.cg_free, d);
5144240Smckusick 		}
5154240Smckusick 		for (; d < MAXBPG; d++)
5164240Smckusick 			clrbit(cgrp.cg_free, d);
5174240Smckusick 		sblock.fs_nffree += cgrp.cg_nffree;
5184240Smckusick 		sblock.fs_nbfree += cgrp.cg_nbfree;
5194240Smckusick 		cs->cs_ndir = cgrp.cg_ndir;
5204240Smckusick 		cs->cs_nifree = cgrp.cg_nifree;
5214240Smckusick 		cs->cs_nbfree = cgrp.cg_nbfree;
5224240Smckusick 		bwrite(cgtod(c, &sblock), (char *)&cgrp, sblock.fs_cgsize);
5234240Smckusick 	}
5244240Smckusick 	sblock.fs_ronly = 0;
5254240Smckusick 	sblock.fs_fmod = 0;
5264240Smckusick 	bwrite(SBLOCK, (char *)&sblock, sizeof (sblock));
5274410Smckusic 	lseek(fi, csaddr(&sblock) * FSIZE, 0);
5284240Smckusick 	if (write(fi,(char *)sblock.fs_cs,cssize(&sblock)) != cssize(&sblock))
5294240Smckusick 		printf("write error %d\n", tell(fi)/BSIZE);
5304240Smckusick }
531