xref: /csrg-svn/sbin/icheck/icheck.c (revision 4240)
1*4240Smckusick static	char *sccsid = "@(#)icheck.c	1.1 (Berkeley) 08/26/81";
2*4240Smckusick /*
3*4240Smckusick  * icheck
4*4240Smckusick  */
5*4240Smckusick #define	NB	500
6*4240Smckusick #define	BITS	8
7*4240Smckusick #define	MAXFN	500
8*4240Smckusick 
9*4240Smckusick #ifndef STANDALONE
10*4240Smckusick #include <stdio.h>
11*4240Smckusick #endif
12*4240Smckusick #include "../h/param.h"
13*4240Smckusick #include "../h/inode.h"
14*4240Smckusick #include "../h/ino.h"
15*4240Smckusick #include "../h/fs.h"
16*4240Smckusick 
17*4240Smckusick #define	setbit(a, i)	((a)[(i)/NBBY] |= 1<<((i)%NBBY))
18*4240Smckusick #define	clrbit(a, i)	((a)[(i)/NBBY] &= ~(1<<((i)%NBBY)))
19*4240Smckusick #define	isset(a,i)	((a)[(i)/NBBY] & (1<<((i)%NBBY)))
20*4240Smckusick 
21*4240Smckusick union {
22*4240Smckusick 	struct	fs sb;
23*4240Smckusick 	char pad[BSIZE];
24*4240Smckusick } sbun;
25*4240Smckusick #define	sblock sbun.sb
26*4240Smckusick 
27*4240Smckusick union {
28*4240Smckusick 	struct	cg cg;
29*4240Smckusick 	char pad[BSIZE];
30*4240Smckusick } cgun;
31*4240Smckusick #define	cgrp cgun.cg
32*4240Smckusick 
33*4240Smckusick struct	dinode	itab[MAXIPG];
34*4240Smckusick daddr_t	iaddr[NDADDR+NIADDR];
35*4240Smckusick daddr_t	blist[NB];
36*4240Smckusick char	*bmap;
37*4240Smckusick 
38*4240Smckusick int	sflg;
39*4240Smckusick int	mflg;
40*4240Smckusick int	dflg;
41*4240Smckusick int	fi;
42*4240Smckusick ino_t	ino;
43*4240Smckusick int	cginit;
44*4240Smckusick 
45*4240Smckusick ino_t	nrfile;
46*4240Smckusick ino_t	ndfile;
47*4240Smckusick ino_t	nbfile;
48*4240Smckusick ino_t	ncfile;
49*4240Smckusick ino_t	nmcfile;
50*4240Smckusick 
51*4240Smckusick daddr_t	nblock;
52*4240Smckusick daddr_t	nfrag;
53*4240Smckusick long	szfrag;
54*4240Smckusick daddr_t	nindir;
55*4240Smckusick long	szindir;
56*4240Smckusick daddr_t	niindir;
57*4240Smckusick 
58*4240Smckusick daddr_t	nffree;
59*4240Smckusick long	szffree;
60*4240Smckusick daddr_t	nbfree;
61*4240Smckusick 
62*4240Smckusick daddr_t	ndup;
63*4240Smckusick 
64*4240Smckusick int	nerror;
65*4240Smckusick 
66*4240Smckusick long	atol();
67*4240Smckusick daddr_t	alloc();
68*4240Smckusick #ifndef STANDALONE
69*4240Smckusick char	*malloc();
70*4240Smckusick #endif
71*4240Smckusick 
72*4240Smckusick main(argc, argv)
73*4240Smckusick char *argv[];
74*4240Smckusick {
75*4240Smckusick 	register i;
76*4240Smckusick 	long n;
77*4240Smckusick 
78*4240Smckusick 	blist[0] = -1;
79*4240Smckusick #ifndef STANDALONE
80*4240Smckusick 	while (--argc) {
81*4240Smckusick 		argv++;
82*4240Smckusick 		if (**argv=='-')
83*4240Smckusick 		switch ((*argv)[1]) {
84*4240Smckusick 		case 'd':
85*4240Smckusick 			dflg++;
86*4240Smckusick 			continue;
87*4240Smckusick 
88*4240Smckusick 		case 'm':
89*4240Smckusick 			mflg++;
90*4240Smckusick 			continue;
91*4240Smckusick 
92*4240Smckusick 		case 's':
93*4240Smckusick 			sflg++;
94*4240Smckusick 			continue;
95*4240Smckusick 
96*4240Smckusick 		case 'b':
97*4240Smckusick 			for(i=0; i<NB; i++) {
98*4240Smckusick 				n = atol(argv[1]);
99*4240Smckusick 				if(n == 0)
100*4240Smckusick 					break;
101*4240Smckusick 				blist[i] = n;
102*4240Smckusick 				argv++;
103*4240Smckusick 				argc--;
104*4240Smckusick 			}
105*4240Smckusick 			blist[i] = -1;
106*4240Smckusick 			continue;
107*4240Smckusick 
108*4240Smckusick 		default:
109*4240Smckusick 			printf("Bad flag\n");
110*4240Smckusick 		}
111*4240Smckusick 		check(*argv);
112*4240Smckusick 	}
113*4240Smckusick #else
114*4240Smckusick 	{
115*4240Smckusick 		static char fname[128];
116*4240Smckusick 
117*4240Smckusick 		printf("File: ");
118*4240Smckusick 		gets(fname);
119*4240Smckusick 		check(fname);
120*4240Smckusick 	}
121*4240Smckusick #endif
122*4240Smckusick 	return(nerror);
123*4240Smckusick }
124*4240Smckusick 
125*4240Smckusick check(file)
126*4240Smckusick char *file;
127*4240Smckusick {
128*4240Smckusick 	register i, j, c;
129*4240Smckusick 	daddr_t d, cgd, cbase, b;
130*4240Smckusick 	long n;
131*4240Smckusick 
132*4240Smckusick 	fi = open(file, sflg?2:0);
133*4240Smckusick 	if (fi < 0) {
134*4240Smckusick 		printf("cannot open %s\n", file);
135*4240Smckusick 		nerror |= 04;
136*4240Smckusick 		return;
137*4240Smckusick 	}
138*4240Smckusick 	printf("%s:\n", file);
139*4240Smckusick 	nrfile = 0;
140*4240Smckusick 	ndfile = 0;
141*4240Smckusick 	ncfile = 0;
142*4240Smckusick 	nbfile = 0;
143*4240Smckusick 	nmcfile = 0;
144*4240Smckusick 
145*4240Smckusick 	nblock = 0;
146*4240Smckusick 	nfrag = 0;
147*4240Smckusick 	szfrag = 0;
148*4240Smckusick 	nindir = 0;
149*4240Smckusick 	szindir = 0;
150*4240Smckusick 	niindir = 0;
151*4240Smckusick 
152*4240Smckusick 	ndup = 0;
153*4240Smckusick #ifndef STANDALONE
154*4240Smckusick 	sync();
155*4240Smckusick #endif
156*4240Smckusick 	bread(SBLOCK, (char *)&sblock, BSIZE);
157*4240Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
158*4240Smckusick 		printf("%s: bad magic number\n", file);
159*4240Smckusick 		nerror |= 04;
160*4240Smckusick 		return;
161*4240Smckusick 	}
162*4240Smckusick 	sblock.fs_cs =
163*4240Smckusick 	    (struct csum *)calloc(howmany(cssize(&sblock), BSIZE), BSIZE);
164*4240Smckusick 	lseek(fi, csaddr(&sblock)*FSIZE, 0);
165*4240Smckusick 	read(fi, (char *)sblock.fs_cs, cssize(&sblock));
166*4240Smckusick 	ino = 0;
167*4240Smckusick 	n = (sblock.fs_size*FRAG + BITS-1) / BITS;
168*4240Smckusick #ifdef STANDALONE
169*4240Smckusick 	bmap = NULL;
170*4240Smckusick #else
171*4240Smckusick 	bmap = malloc((unsigned)n);
172*4240Smckusick #endif
173*4240Smckusick 	if (bmap==NULL) {
174*4240Smckusick 		printf("Not enough core; duplicates unchecked\n");
175*4240Smckusick 		dflg++;
176*4240Smckusick 		sflg = 0;
177*4240Smckusick 	}
178*4240Smckusick 	ino = 0;
179*4240Smckusick 	cginit = 1;
180*4240Smckusick 	if(!dflg) {
181*4240Smckusick 		for (i=0; i<(unsigned)n; i++)
182*4240Smckusick 			bmap[i] = 0;
183*4240Smckusick 		for (c=0; c < sblock.fs_ncg; c++) {
184*4240Smckusick 			cgd = cgtod(c, &sblock);
185*4240Smckusick 			for (d = cgbase(c, &sblock); d < cgd; d++)
186*4240Smckusick 				chk(d, "badcg");
187*4240Smckusick 			d = cgimin(c, &sblock);
188*4240Smckusick 			while (cgd < d) {
189*4240Smckusick 				chk(cgd, "cg");
190*4240Smckusick 				cgd++;
191*4240Smckusick 			}
192*4240Smckusick 			d = cgdmin(c, &sblock);
193*4240Smckusick 			for (; cgd < d; cgd++)
194*4240Smckusick 				chk(cgd, "inode");
195*4240Smckusick 			if (c == 0) {
196*4240Smckusick 				d += howmany(cssize(&sblock), BSIZE) * FRAG;
197*4240Smckusick 				for (; cgd < d; cgd++)
198*4240Smckusick 					chk(cgd, "csum");
199*4240Smckusick 			}
200*4240Smckusick 		}
201*4240Smckusick 	}
202*4240Smckusick 	cginit = 0;
203*4240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
204*4240Smckusick 		bread(cgimin(c,&sblock), (char *)itab,
205*4240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
206*4240Smckusick 		for (j=0; j < sblock.fs_ipg; j++) {
207*4240Smckusick 			pass1(&itab[j]);
208*4240Smckusick 			ino++;
209*4240Smckusick 		}
210*4240Smckusick 	}
211*4240Smckusick 	ino = 0;
212*4240Smckusick #ifndef STANDALONE
213*4240Smckusick 	sync();
214*4240Smckusick #endif
215*4240Smckusick 	bread(SBLOCK, (char *)&sblock, sizeof(sblock));
216*4240Smckusick 	if (sflg) {
217*4240Smckusick 		makecg();
218*4240Smckusick 		close(fi);
219*4240Smckusick #ifndef STANDALONE
220*4240Smckusick 		if (bmap)
221*4240Smckusick 			free(bmap);
222*4240Smckusick #endif
223*4240Smckusick 		return;
224*4240Smckusick 	}
225*4240Smckusick 	nffree = 0;
226*4240Smckusick 	szffree = 0;
227*4240Smckusick 	nbfree = 0;
228*4240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
229*4240Smckusick 		cbase = cgbase(c,&sblock);
230*4240Smckusick 		bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize);
231*4240Smckusick 		for (b = 0; b < sblock.fs_fpg; b += FRAG) {
232*4240Smckusick 			if (isblock(cgrp.cg_free, b / FRAG)) {
233*4240Smckusick 				nbfree++;
234*4240Smckusick 				for (d = 0; d < FRAG; d++)
235*4240Smckusick 					chk(cbase+b+d, "block");
236*4240Smckusick 			} else {
237*4240Smckusick 				for (d = 0; d < FRAG; d++)
238*4240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
239*4240Smckusick 						chk(cbase+b+d, "frag");
240*4240Smckusick 						nffree++;
241*4240Smckusick 						szffree++;
242*4240Smckusick 					}
243*4240Smckusick 			}
244*4240Smckusick 		}
245*4240Smckusick 	}
246*4240Smckusick 	close(fi);
247*4240Smckusick #ifndef STANDALONE
248*4240Smckusick 	if (bmap)
249*4240Smckusick 		free(bmap);
250*4240Smckusick #endif
251*4240Smckusick 
252*4240Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nmcfile;
253*4240Smckusick #ifndef STANDALONE
254*4240Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
255*4240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
256*4240Smckusick #else
257*4240Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
258*4240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
259*4240Smckusick #endif
260*4240Smckusick 	n = (nblock + niindir) * FRAG + szfrag + szindir;
261*4240Smckusick #ifdef STANDALONE
262*4240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
263*4240Smckusick 		n, nindir, niindir, nblock, nfrag);
264*4240Smckusick 	printf("free %ld (b=%ld,f=%ld)\n", szffree + FRAG * nbfree,
265*4240Smckusick 	    nbfree, nffree);
266*4240Smckusick #else
267*4240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
268*4240Smckusick 		n, nindir, niindir, nblock, nfrag);
269*4240Smckusick 	printf("free %7ld (b=%ld,f=%ld)\n", szffree + FRAG * nbfree,
270*4240Smckusick 	    nbfree, nffree);
271*4240Smckusick #endif
272*4240Smckusick 	if(!dflg) {
273*4240Smckusick 		n = 0;
274*4240Smckusick 		for(d=0; d<sblock.fs_size; d++)
275*4240Smckusick 			if(!duped(d)) {
276*4240Smckusick 				if(mflg)
277*4240Smckusick 					printf("%ld missing\n", d);
278*4240Smckusick 				n++;
279*4240Smckusick 			}
280*4240Smckusick 		printf("missing%5ld\n", n);
281*4240Smckusick 	}
282*4240Smckusick }
283*4240Smckusick 
284*4240Smckusick pass1(ip)
285*4240Smckusick register struct dinode *ip;
286*4240Smckusick {
287*4240Smckusick 	daddr_t ind1[NINDIR];
288*4240Smckusick 	daddr_t ind2[NINDIR];
289*4240Smckusick 	register i, j;
290*4240Smckusick 	int k, l, sz, ni, nib, ndb;
291*4240Smckusick 
292*4240Smckusick 	i = ip->di_mode & IFMT;
293*4240Smckusick 	if(i == 0) {
294*4240Smckusick 		sblock.fs_nifree++;
295*4240Smckusick 		return;
296*4240Smckusick 	}
297*4240Smckusick 	switch (i) {
298*4240Smckusick 	case IFCHR:
299*4240Smckusick 		ncfile++;
300*4240Smckusick 		return;
301*4240Smckusick 	case IFBLK:
302*4240Smckusick 		nbfile++;
303*4240Smckusick 		return;
304*4240Smckusick 	case IFDIR:
305*4240Smckusick 		ndfile++;
306*4240Smckusick 		break;
307*4240Smckusick 	case IFREG:
308*4240Smckusick 		nrfile++;
309*4240Smckusick 		break;
310*4240Smckusick 	default:
311*4240Smckusick 		printf("bad mode %u\n", ino);
312*4240Smckusick 		return;
313*4240Smckusick 	}
314*4240Smckusick 	l3tol(iaddr, ip->di_addr, NDADDR+NIADDR);
315*4240Smckusick 	ndb = howmany(ip->di_size, BSIZE)-1;
316*4240Smckusick 	for(i=0; i<NDADDR; i++) {
317*4240Smckusick 		if(iaddr[i] == 0)
318*4240Smckusick 			continue;
319*4240Smckusick 		if (i==ndb && (ip->di_size&BMASK)) {
320*4240Smckusick 			sz = howmany(ip->di_size - i * BSIZE, FSIZE);
321*4240Smckusick 			for (l = 0; l < sz; l++)
322*4240Smckusick 				chk(iaddr[i]+l, "data (frag)");
323*4240Smckusick 			szfrag += sz;
324*4240Smckusick 			nfrag++;
325*4240Smckusick 		} else {
326*4240Smckusick 			for (l = 0; l < FRAG; l++)
327*4240Smckusick 				chk(iaddr[i]+l, "data (block)");
328*4240Smckusick 			nblock++;
329*4240Smckusick 		}
330*4240Smckusick 	}
331*4240Smckusick 	for(i=NDADDR; i<NDADDR+NIADDR;i++) {
332*4240Smckusick 		if(iaddr[i] == 0)
333*4240Smckusick 			continue;
334*4240Smckusick 		nindir++;
335*4240Smckusick 		if (i==NDADDR) {
336*4240Smckusick 			sz = howmany((ip->di_size-NDADDR*BSIZE),
337*4240Smckusick 			    (NINDIR/FRAG) * BSIZE);
338*4240Smckusick 			if (sz > FRAG)
339*4240Smckusick 				sz = FRAG;
340*4240Smckusick 		} else
341*4240Smckusick 			sz = FRAG;
342*4240Smckusick 		for (j = 0; j < FRAG; j++)
343*4240Smckusick 			if (chk(iaddr[i]+j, "1st indirect"))
344*4240Smckusick 				continue;
345*4240Smckusick 		bread(iaddr[i], (char *)ind1, sz*FSIZE);
346*4240Smckusick 		nib = sz * (NINDIR/FRAG);
347*4240Smckusick 		for(j=0; j<nib; j++) {
348*4240Smckusick 			if(ind1[j] == 0)
349*4240Smckusick 				continue;
350*4240Smckusick 			if(i == NDADDR) {
351*4240Smckusick 				for (l = 0; l < FRAG; l++)
352*4240Smckusick 					chk(ind1[j]+l, "data (large)");
353*4240Smckusick 				nblock++;
354*4240Smckusick 				continue;
355*4240Smckusick 			}
356*4240Smckusick 			niindir++;
357*4240Smckusick 			for (l = 0; l < FRAG; l++)
358*4240Smckusick 				if(chk(ind1[j], "2nd indirect"))
359*4240Smckusick 					goto skip;
360*4240Smckusick 			bread(ind1[j], (char *)ind2, BSIZE);
361*4240Smckusick 			for(k=0; k<NINDIR; k++) {
362*4240Smckusick 				if(ind2[k] == 0)
363*4240Smckusick 					continue;
364*4240Smckusick 				for (l = 0; l < FRAG; l++)
365*4240Smckusick 					chk(ind1[j]+l, "data (huge)");
366*4240Smckusick 				nblock++;
367*4240Smckusick 				continue;
368*4240Smckusick 			}
369*4240Smckusick skip:
370*4240Smckusick 			;
371*4240Smckusick 		}
372*4240Smckusick 	}
373*4240Smckusick }
374*4240Smckusick 
375*4240Smckusick chk(bno, s)
376*4240Smckusick daddr_t bno;
377*4240Smckusick char *s;
378*4240Smckusick {
379*4240Smckusick 	register n, cg;
380*4240Smckusick 
381*4240Smckusick 	cg = dtog(bno, &sblock);
382*4240Smckusick 	if (cginit==0 && bno<cgdmin(cg,&sblock) || bno>=FRAG*sblock.fs_size) {
383*4240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
384*4240Smckusick 		return(1);
385*4240Smckusick 	}
386*4240Smckusick 	if (duped(bno)) {
387*4240Smckusick 		printf("%ld dup; inode=%u, class=%s\n", bno, ino, s);
388*4240Smckusick 		ndup++;
389*4240Smckusick 	}
390*4240Smckusick 	for (n=0; blist[n] != -1; n++)
391*4240Smckusick 		if (bno == blist[n])
392*4240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
393*4240Smckusick 	return(0);
394*4240Smckusick }
395*4240Smckusick 
396*4240Smckusick duped(bno)
397*4240Smckusick daddr_t bno;
398*4240Smckusick {
399*4240Smckusick 	daddr_t d;
400*4240Smckusick 	register m, n;
401*4240Smckusick 
402*4240Smckusick 	if(dflg)
403*4240Smckusick 		return(0);
404*4240Smckusick 	m = 1 << (bno%BITS);
405*4240Smckusick 	n = (bno/BITS);
406*4240Smckusick 	if(bmap[n] & m)
407*4240Smckusick 		return(1);
408*4240Smckusick 	bmap[n] |= m;
409*4240Smckusick 	return(0);
410*4240Smckusick }
411*4240Smckusick 
412*4240Smckusick bread(bno, buf, cnt)
413*4240Smckusick daddr_t bno;
414*4240Smckusick char *buf;
415*4240Smckusick {
416*4240Smckusick 	register i;
417*4240Smckusick 
418*4240Smckusick 	lseek(fi, bno*FSIZE, 0);
419*4240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
420*4240Smckusick 		if (sflg) {
421*4240Smckusick 			printf("No update\n");
422*4240Smckusick 			sflg = 0;
423*4240Smckusick 		}
424*4240Smckusick 		for(i=0; i<BSIZE; i++)
425*4240Smckusick 			buf[i] = 0;
426*4240Smckusick 	}
427*4240Smckusick }
428*4240Smckusick 
429*4240Smckusick bwrite(bno, buf, cnt)
430*4240Smckusick daddr_t bno;
431*4240Smckusick char *buf;
432*4240Smckusick {
433*4240Smckusick 	register i;
434*4240Smckusick 
435*4240Smckusick 	lseek(fi, bno*FSIZE, 0);
436*4240Smckusick 	if (write(fi, buf, cnt) != cnt)
437*4240Smckusick 		printf("write error %d\n", tell(fi)/BSIZE);
438*4240Smckusick }
439*4240Smckusick 
440*4240Smckusick makecg()
441*4240Smckusick {
442*4240Smckusick 	int c;
443*4240Smckusick 	daddr_t dbase, d, dmin, dmax;
444*4240Smckusick 	long i, j, s;
445*4240Smckusick 	register struct csum *cs;
446*4240Smckusick 
447*4240Smckusick 	sblock.fs_nbfree = 0;
448*4240Smckusick 	sblock.fs_nffree = 0;
449*4240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
450*4240Smckusick 		bread(cgimin(c,&sblock), (char *)itab,
451*4240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
452*4240Smckusick 		dbase = cgbase(c, &sblock);
453*4240Smckusick 		dmax = dbase + sblock.fs_fpg;
454*4240Smckusick 		if (dmax > sblock.fs_size)
455*4240Smckusick 			dmax = sblock.fs_size;
456*4240Smckusick 		cs = &sblock.fs_cs[c];
457*4240Smckusick 		cgrp.cg_time = time(0);
458*4240Smckusick 		cgrp.cg_magic = CG_MAGIC;
459*4240Smckusick 		cgrp.cg_cgx = c;
460*4240Smckusick 		cgrp.cg_ncyl = sblock.fs_cpg;
461*4240Smckusick 		cgrp.cg_niblk = sblock.fs_ipg;
462*4240Smckusick 		cgrp.cg_ndblk = dmax - dbase;
463*4240Smckusick 		cgrp.cg_ndir = 0;
464*4240Smckusick 		cgrp.cg_nffree = 0;
465*4240Smckusick 		cgrp.cg_nbfree = 0;
466*4240Smckusick 		cgrp.cg_nifree = 0;
467*4240Smckusick 		for (i = 0; i < sblock.fs_ipg; i++)
468*4240Smckusick 		switch (itab[i].di_mode&IFMT) {
469*4240Smckusick 
470*4240Smckusick 		case 0:
471*4240Smckusick 			cgrp.cg_nifree++;
472*4240Smckusick 			clrbit(cgrp.cg_iused, i);
473*4240Smckusick 			continue;
474*4240Smckusick 
475*4240Smckusick 		case IFDIR:
476*4240Smckusick 			cgrp.cg_ndir++;
477*4240Smckusick 			/* fall into ... */
478*4240Smckusick 
479*4240Smckusick 		default:
480*4240Smckusick 			setbit(cgrp.cg_iused, i);
481*4240Smckusick 			continue;
482*4240Smckusick 		}
483*4240Smckusick 		while (i < MAXIPG) {
484*4240Smckusick 			clrbit(cgrp.cg_iused, i);
485*4240Smckusick 			i++;
486*4240Smckusick 		}
487*4240Smckusick 		for (s = 0; s < MAXCPG; s++)
488*4240Smckusick 			for (i = 0; i < NRPOS; i++)
489*4240Smckusick 				cgrp.cg_b[s][i] = 0;
490*4240Smckusick 		dmin = cgdmin(c, &sblock) - dbase;
491*4240Smckusick 		if (c == 0)
492*4240Smckusick 			dmin += howmany(cssize(&sblock), BSIZE) * FRAG;
493*4240Smckusick 		for (d = 0; d < dmin; d++)
494*4240Smckusick 			clrbit(cgrp.cg_free, d);
495*4240Smckusick #define	getbmap(i) isset(bmap, i)
496*4240Smckusick 		for (; (d + FRAG) <= dmax - dbase; d += FRAG) {
497*4240Smckusick 			j = 0;
498*4240Smckusick 			for (i = 0; i < FRAG; i++) {
499*4240Smckusick 				if (!getbmap(dbase+d+i)) {
500*4240Smckusick 					setbit(cgrp.cg_free, d+i);
501*4240Smckusick 					j++;
502*4240Smckusick 				} else
503*4240Smckusick 					clrbit(cgrp.cg_free, d+i);
504*4240Smckusick 			}
505*4240Smckusick 			if (j == FRAG) {
506*4240Smckusick 				cgrp.cg_nbfree++;
507*4240Smckusick 				s = d * NSPF;
508*4240Smckusick 				cgrp.cg_b[s/sblock.fs_spc]
509*4240Smckusick 				  [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++;
510*4240Smckusick 			} else
511*4240Smckusick 				cgrp.cg_nffree += j;
512*4240Smckusick 		}
513*4240Smckusick 		for (; d < dmax - dbase; d++) {
514*4240Smckusick 			if (!getbmap(dbase+d)) {
515*4240Smckusick 				setbit(cgrp.cg_free, d);
516*4240Smckusick 				cgrp.cg_nffree++;
517*4240Smckusick 			} else
518*4240Smckusick 				clrbit(cgrp.cg_free, d);
519*4240Smckusick 		}
520*4240Smckusick 		for (; d < MAXBPG; d++)
521*4240Smckusick 			clrbit(cgrp.cg_free, d);
522*4240Smckusick 		sblock.fs_nffree += cgrp.cg_nffree;
523*4240Smckusick 		sblock.fs_nbfree += cgrp.cg_nbfree;
524*4240Smckusick 		cs->cs_ndir = cgrp.cg_ndir;
525*4240Smckusick 		cs->cs_nifree = cgrp.cg_nifree;
526*4240Smckusick 		cs->cs_nbfree = cgrp.cg_nbfree;
527*4240Smckusick 		bwrite(cgtod(c, &sblock), (char *)&cgrp, sblock.fs_cgsize);
528*4240Smckusick 	}
529*4240Smckusick 	sblock.fs_ronly = 0;
530*4240Smckusick 	sblock.fs_fmod = 0;
531*4240Smckusick 	bwrite(SBLOCK, (char *)&sblock, sizeof (sblock));
532*4240Smckusick 	lseek(fi, csaddr(&sblock)*FSIZE, 0);
533*4240Smckusick 	if (write(fi,(char *)sblock.fs_cs,cssize(&sblock)) != cssize(&sblock))
534*4240Smckusick 		printf("write error %d\n", tell(fi)/BSIZE);
535*4240Smckusick }
536