xref: /csrg-svn/sbin/icheck/icheck.c (revision 5326)
1*5326Smckusic static	char *sccsid = "@(#)icheck.c	1.10 (Berkeley) 01/05/82";
24410Smckusic 
34240Smckusick /*
44240Smckusick  * icheck
54240Smckusick  */
64240Smckusick #define	NB	500
74240Smckusick #define	MAXFN	500
8*5326Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
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;
19*5326Smckusic 	char pad[MAXBSIZE];
204240Smckusick } sbun;
214240Smckusick #define	sblock sbun.sb
224240Smckusick 
234240Smckusick union {
244240Smckusick 	struct	cg cg;
25*5326Smckusic 	char pad[MAXBSIZE];
264240Smckusick } cgun;
274240Smckusick #define	cgrp cgun.cg
284240Smckusick 
294240Smckusick struct	dinode	itab[MAXIPG];
304240Smckusick daddr_t	blist[NB];
314240Smckusick char	*bmap;
324240Smckusick 
334240Smckusick int	mflg;
345098Smckusic int	sflg;
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 
585098Smckusic extern int inside[], around[];
59*5326Smckusic extern unsigned char *fragtbl[];
605098Smckusic 
614240Smckusick long	atol();
624240Smckusick #ifndef STANDALONE
634240Smckusick char	*malloc();
645098Smckusic char	*calloc();
654240Smckusick #endif
664240Smckusick 
674240Smckusick main(argc, argv)
685098Smckusic 	int argc;
695098Smckusic 	char *argv[];
704240Smckusick {
714240Smckusick 	register i;
724240Smckusick 	long n;
734240Smckusick 
744240Smckusick 	blist[0] = -1;
754240Smckusick #ifndef STANDALONE
764240Smckusick 	while (--argc) {
774240Smckusick 		argv++;
784240Smckusick 		if (**argv=='-')
794240Smckusick 		switch ((*argv)[1]) {
804240Smckusick 		case 'd':
814240Smckusick 			dflg++;
824240Smckusick 			continue;
834240Smckusick 
844240Smckusick 		case 'm':
854240Smckusick 			mflg++;
864240Smckusick 			continue;
874240Smckusick 
885098Smckusic 		case 's':
895098Smckusic 			sflg++;
905098Smckusic 			continue;
915098Smckusic 
924240Smckusick 		case 'b':
934240Smckusick 			for(i=0; i<NB; i++) {
944240Smckusick 				n = atol(argv[1]);
954240Smckusick 				if(n == 0)
964240Smckusick 					break;
974240Smckusick 				blist[i] = n;
984240Smckusick 				argv++;
994240Smckusick 				argc--;
1004240Smckusick 			}
1014240Smckusick 			blist[i] = -1;
1024240Smckusick 			continue;
1034240Smckusick 
1044240Smckusick 		default:
1054240Smckusick 			printf("Bad flag\n");
1064240Smckusick 		}
1074240Smckusick 		check(*argv);
1084240Smckusick 	}
1094240Smckusick #else
1104240Smckusick 	{
1114240Smckusick 		static char fname[128];
1124240Smckusick 
1134240Smckusick 		printf("File: ");
1144240Smckusick 		gets(fname);
1154240Smckusick 		check(fname);
1164240Smckusick 	}
1174240Smckusick #endif
1184240Smckusick 	return(nerror);
1194240Smckusick }
1204240Smckusick 
1214240Smckusick check(file)
1225098Smckusic 	char *file;
1234240Smckusick {
1244240Smckusick 	register i, j, c;
1254240Smckusick 	daddr_t d, cgd, cbase, b;
1264240Smckusick 	long n;
1274240Smckusick 
1285098Smckusic 	fi = open(file, sflg ? 2 : 0);
1294240Smckusick 	if (fi < 0) {
1305098Smckusic 		perror(file);
1314240Smckusick 		nerror |= 04;
1324240Smckusick 		return;
1334240Smckusick 	}
1344240Smckusick 	printf("%s:\n", file);
1354240Smckusick 	nrfile = 0;
1364240Smckusick 	ndfile = 0;
1374240Smckusick 	ncfile = 0;
1384240Smckusick 	nbfile = 0;
1394240Smckusick 	nmcfile = 0;
1404240Smckusick 
1414240Smckusick 	nblock = 0;
1424240Smckusick 	nfrag = 0;
1434240Smckusick 	nindir = 0;
1444240Smckusick 	niindir = 0;
1454240Smckusick 
1464240Smckusick 	ndup = 0;
1474240Smckusick #ifndef STANDALONE
1484240Smckusick 	sync();
1494240Smckusick #endif
150*5326Smckusic 	getsb(&sblock, file);
151*5326Smckusic 	if (nerror)
1524240Smckusick 		return;
1534240Smckusick 	ino = 0;
1545098Smckusic 	n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
1554240Smckusick #ifdef STANDALONE
1564240Smckusick 	bmap = NULL;
1574240Smckusick #else
1584240Smckusick 	bmap = malloc((unsigned)n);
1594240Smckusick #endif
1604240Smckusick 	if (bmap==NULL) {
1614240Smckusick 		printf("Not enough core; duplicates unchecked\n");
1624240Smckusick 		dflg++;
1635098Smckusic 		if (sflg) {
1645098Smckusic 			printf("No Updates\n");
1655098Smckusic 			sflg = 0;
1665098Smckusic 		}
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);
175*5326Smckusic 			for (d = cgbase(c, &sblock); d < cgd; d += sblock.fs_frag)
176*5326Smckusic 				chk(d, "badcg", sblock.fs_bsize);
1774240Smckusick 			d = cgimin(c, &sblock);
1784240Smckusick 			while (cgd < d) {
179*5326Smckusic 				chk(cgd, "cg", sblock.fs_bsize);
180*5326Smckusic 				cgd += sblock.fs_frag;
1814240Smckusick 			}
1824240Smckusick 			d = cgdmin(c, &sblock);
183*5326Smckusic 			for (; cgd < d; cgd += sblock.fs_frag)
184*5326Smckusic 				chk(cgd, "inode", sblock.fs_bsize);
1854240Smckusick 			if (c == 0) {
186*5326Smckusic 				d += howmany(sblock.fs_cssize, sblock.fs_bsize)
187*5326Smckusic 				    * sblock.fs_frag;
188*5326Smckusic 				for (; cgd < d; cgd += sblock.fs_frag)
189*5326Smckusic 					chk(cgd, "csum", sblock.fs_bsize);
1904240Smckusick 			}
1914240Smckusick 		}
1924240Smckusick 	}
1934240Smckusick 	cginit = 0;
1944240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
195*5326Smckusic 		bread(fsbtodb(&sblock, cgimin(c,&sblock)), (char *)itab,
1964240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1974240Smckusick 		for (j=0; j < sblock.fs_ipg; j++) {
1984240Smckusick 			pass1(&itab[j]);
1994240Smckusick 			ino++;
2004240Smckusick 		}
2014240Smckusick 	}
2024240Smckusick 	ino = 0;
2034240Smckusick #ifndef STANDALONE
2044240Smckusick 	sync();
2054240Smckusick #endif
2065098Smckusic 	if (sflg) {
2075098Smckusic 		makecg();
2085098Smckusic 		close(fi);
2095098Smckusic #ifndef STANDALONE
2105098Smckusic 		if (bmap)
2115098Smckusic 			free(bmap);
2125098Smckusic #endif
2135098Smckusic 		return;
2145098Smckusic 	}
2154240Smckusick 	nffree = 0;
2164240Smckusick 	nbfree = 0;
2174240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2184240Smckusick 		cbase = cgbase(c,&sblock);
219*5326Smckusic 		bread(fsbtodb(&sblock, cgtod(c,&sblock)), (char *)&cgrp,
220*5326Smckusic 			sblock.fs_cgsize);
221*5326Smckusic 		for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
222*5326Smckusic 			if (isblock(&sblock, cgrp.cg_free,
223*5326Smckusic 			    b / sblock.fs_frag)) {
2244240Smckusick 				nbfree++;
225*5326Smckusic 				chk(cbase+b, "block", sblock.fs_bsize);
2264240Smckusick 			} else {
227*5326Smckusic 				for (d = 0; d < sblock.fs_frag; d++)
2284240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
229*5326Smckusic 						chk(cbase+b+d, "frag", sblock.fs_fsize);
2304240Smckusick 						nffree++;
2314240Smckusick 					}
2324240Smckusick 			}
2334240Smckusick 		}
2344240Smckusick 	}
2354240Smckusick 	close(fi);
2364240Smckusick #ifndef STANDALONE
2374240Smckusick 	if (bmap)
2384240Smckusick 		free(bmap);
2394240Smckusick #endif
2404240Smckusick 
2414240Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nmcfile;
2424240Smckusick #ifndef STANDALONE
2434240Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2444240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2454240Smckusick #else
2464240Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2474240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2484240Smckusick #endif
249*5326Smckusic 	n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
2504240Smckusick #ifdef STANDALONE
2514240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2524240Smckusick 		n, nindir, niindir, nblock, nfrag);
253*5326Smckusic 	printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
2544240Smckusick 	    nbfree, nffree);
2554240Smckusick #else
2564240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2574240Smckusick 		n, nindir, niindir, nblock, nfrag);
258*5326Smckusic 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
2594240Smckusick 	    nbfree, nffree);
2604240Smckusick #endif
2614240Smckusick 	if(!dflg) {
2624240Smckusick 		n = 0;
2634410Smckusic 		for (d = 0; d < sblock.fs_size; d++)
264*5326Smckusic 			if(!duped(d, sblock.fs_fsize)) {
2654240Smckusick 				if(mflg)
2664240Smckusick 					printf("%ld missing\n", d);
2674240Smckusick 				n++;
2684240Smckusick 			}
2694240Smckusick 		printf("missing%5ld\n", n);
2704240Smckusick 	}
2714240Smckusick }
2724240Smckusick 
2734240Smckusick pass1(ip)
2744410Smckusic 	register struct dinode *ip;
2754240Smckusick {
276*5326Smckusic 	daddr_t ind1[MAXNINDIR];
277*5326Smckusic 	daddr_t ind2[MAXNINDIR];
2784429Smckusic 	daddr_t db, ib;
2794429Smckusic 	register int i, j, k, siz;
2804240Smckusick 
2814240Smckusick 	i = ip->di_mode & IFMT;
2824790Smckusic 	if(i == 0)
2834240Smckusick 		return;
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*5326Smckusic 		siz = dblksize(&sblock, ip, i);
3064429Smckusic 		chk(db, "data (block)", siz);
307*5326Smckusic 		if (siz == sblock.fs_bsize)
3084429Smckusic 			nblock++;
3094429Smckusic 		else
310*5326Smckusic 			nfrag += howmany(siz, sblock.fs_fsize);
3114240Smckusick 	}
3124410Smckusic 	for(i = 0; i < NIADDR; i++) {
3134410Smckusic 		ib = ip->di_ib[i];
3144410Smckusic 		if(ib == 0)
3154240Smckusick 			continue;
316*5326Smckusic 		if (chk(ib, "1st indirect", sblock.fs_bsize))
3174410Smckusic 			continue;
318*5326Smckusic 		bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
3194240Smckusick 		nindir++;
320*5326Smckusic 		for (j = 0; j < NINDIR(&sblock); j++) {
3214410Smckusic 			ib = ind1[j];
3224410Smckusic 			if (ib == 0)
3234240Smckusick 				continue;
3244410Smckusic 			if (i == 0) {
325*5326Smckusic 				siz = dblksize(&sblock, ip, NDADDR + j);
3264429Smckusic 				chk(ib, "data (large)", siz);
327*5326Smckusic 				if (siz == sblock.fs_bsize)
3284429Smckusic 					nblock++;
3294429Smckusic 				else
330*5326Smckusic 					nfrag += howmany(siz, sblock.fs_fsize);
3314240Smckusick 				continue;
3324240Smckusick 			}
333*5326Smckusic 			if (chk(ib, "2nd indirect", sblock.fs_bsize))
3344410Smckusic 				continue;
335*5326Smckusic 			bread(fsbtodb(&sblock, ib), (char *)ind2,
336*5326Smckusic 				sblock.fs_bsize);
3374240Smckusick 			niindir++;
338*5326Smckusic 			for (k = 0; k < NINDIR(&sblock); k++) {
3394410Smckusic 				ib = ind2[k];
3404410Smckusic 				if (ib == 0)
3414240Smckusick 					continue;
342*5326Smckusic 				siz = dblksize(&sblock, ip,
343*5326Smckusic 				    NDADDR + NINDIR(&sblock) * (i + j) + k);
3444429Smckusic 				chk(ib, "data (huge)", siz);
345*5326Smckusic 				if (siz == sblock.fs_bsize)
3464429Smckusic 					nblock++;
3474429Smckusic 				else
348*5326Smckusic 					nfrag += howmany(siz, sblock.fs_fsize);
3494240Smckusick 			}
3504240Smckusick 		}
3514240Smckusick 	}
3524240Smckusick }
3534240Smckusick 
3544429Smckusic chk(bno, s, size)
3554410Smckusic 	daddr_t bno;
3564410Smckusic 	char *s;
3574429Smckusic 	int size;
3584240Smckusick {
3594240Smckusick 	register n, cg;
3604240Smckusick 
3614240Smckusick 	cg = dtog(bno, &sblock);
3624429Smckusic 	if (cginit==0 &&
363*5326Smckusic 	    bno<cgdmin(cg,&sblock) || bno >= sblock.fs_frag * sblock.fs_size) {
3644240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
3654240Smckusick 		return(1);
3664240Smckusick 	}
367*5326Smckusic 	if (size == sblock.fs_bsize) {
3684429Smckusic 		if (duped(bno, size)) {
3694429Smckusic 			printf("%ld dup block; inode=%u, class=%s\n",
3704429Smckusic 			    bno, ino, s);
371*5326Smckusic 			ndup += sblock.fs_frag;
3724429Smckusic 		}
3734429Smckusic 	} else {
374*5326Smckusic 		for (n = 0; n < size / sblock.fs_fsize; n++) {
375*5326Smckusic 			if (duped(bno + n, sblock.fs_fsize)) {
3764429Smckusic 				printf("%ld dup frag; inode=%u, class=%s\n",
3774429Smckusic 				    bno, ino, s);
3784429Smckusic 				ndup++;
3794429Smckusic 			}
3804429Smckusic 		}
3814240Smckusick 	}
3824240Smckusick 	for (n=0; blist[n] != -1; n++)
3834240Smckusick 		if (bno == blist[n])
3844240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
3854240Smckusick 	return(0);
3864240Smckusick }
3874240Smckusick 
3884429Smckusic duped(bno, size)
3894410Smckusic 	daddr_t bno;
3904429Smckusic 	int size;
3914240Smckusick {
3924240Smckusick 	if(dflg)
3934240Smckusick 		return(0);
394*5326Smckusic 	if (size != sblock.fs_fsize && size != sblock.fs_bsize)
3954429Smckusic 		printf("bad size %d to duped\n", size);
396*5326Smckusic 	if (size == sblock.fs_fsize) {
3974410Smckusic 		if (isset(bmap, bno))
3984410Smckusic 			return(1);
3994410Smckusic 		setbit(bmap, bno);
4004410Smckusic 		return (0);
4014410Smckusic 	}
402*5326Smckusic 	if (bno % sblock.fs_frag != 0)
4034410Smckusic 		printf("bad bno %d to duped\n", bno);
404*5326Smckusic 	if (isblock(&sblock, bmap, bno/sblock.fs_frag))
4054410Smckusic 		return (1);
406*5326Smckusic 	setblock(&sblock, bmap, bno/sblock.fs_frag);
4074240Smckusick 	return(0);
4084240Smckusick }
4094240Smckusick 
4105098Smckusic makecg()
4115098Smckusic {
4125098Smckusic 	int c, blk;
4135098Smckusic 	daddr_t dbase, d, dmin, dmax;
4145098Smckusic 	long i, j, s;
4155098Smckusic 	register struct csum *cs;
4165098Smckusic 	register struct dinode *dp;
4175098Smckusic 
4185098Smckusic 	sblock.fs_cstotal.cs_nbfree = 0;
4195098Smckusic 	sblock.fs_cstotal.cs_nffree = 0;
4205098Smckusic 	sblock.fs_cstotal.cs_nifree = 0;
4215098Smckusic 	sblock.fs_cstotal.cs_ndir = 0;
4225098Smckusic 	for (c = 0; c < sblock.fs_ncg; c++) {
4235098Smckusic 		dbase = cgbase(c, &sblock);
4245098Smckusic 		dmax = dbase + sblock.fs_fpg;
4255098Smckusic 		if (dmax > sblock.fs_size)
4265098Smckusic 			dmax = sblock.fs_size;
4275098Smckusic 		dmin = cgdmin(c, &sblock) - dbase;
428*5326Smckusic 		cs = &sblock.fs_cs(&sblock, c);
4295098Smckusic 		cgrp.cg_time = time(0);
4305098Smckusic 		cgrp.cg_magic = CG_MAGIC;
4315098Smckusic 		cgrp.cg_cgx = c;
4325098Smckusic 		cgrp.cg_ncyl = sblock.fs_cpg;
4335098Smckusic 		cgrp.cg_niblk = sblock.fs_ipg;
4345098Smckusic 		cgrp.cg_ndblk = dmax - dbase;
4355098Smckusic 		cgrp.cg_cs.cs_ndir = 0;
4365098Smckusic 		cgrp.cg_cs.cs_nffree = 0;
4375098Smckusic 		cgrp.cg_cs.cs_nbfree = 0;
4385098Smckusic 		cgrp.cg_cs.cs_nifree = 0;
4395098Smckusic 		cgrp.cg_rotor = dmin;
4405098Smckusic 		cgrp.cg_frotor = dmin;
4415098Smckusic 		cgrp.cg_irotor = 0;
442*5326Smckusic 		for (i = 0; i < sblock.fs_frag; i++)
4435098Smckusic 			cgrp.cg_frsum[i] = 0;
444*5326Smckusic 		bread(fsbtodb(&sblock, cgimin(c, &sblock)), (char *)itab,
4455098Smckusic 		      sblock.fs_ipg * sizeof(struct dinode));
4465098Smckusic 		for (i = 0; i < sblock.fs_ipg; i++) {
4475098Smckusic 			dp = &itab[i];
4485098Smckusic 			if (dp == NULL)
4495098Smckusic 				continue;
4505098Smckusic 			if ((dp->di_mode & IFMT) != 0) {
4515098Smckusic 				if ((dp->di_mode & IFMT) == IFDIR)
4525098Smckusic 					cgrp.cg_cs.cs_ndir++;
4535098Smckusic 				setbit(cgrp.cg_iused, i);
4545098Smckusic 				continue;
4555098Smckusic 			}
4565098Smckusic 			cgrp.cg_cs.cs_nifree++;
4575098Smckusic 			clrbit(cgrp.cg_iused, i);
4585098Smckusic 		}
4595098Smckusic 		while (i < MAXIPG) {
4605098Smckusic 			clrbit(cgrp.cg_iused, i);
4615098Smckusic 			i++;
4625098Smckusic 		}
4635098Smckusic 		for (s = 0; s < MAXCPG; s++)
4645098Smckusic 			for (i = 0; i < NRPOS; i++)
4655098Smckusic 				cgrp.cg_b[s][i] = 0;
4665098Smckusic 		if (c == 0) {
467*5326Smckusic 			dmin += howmany(sblock.fs_cssize, sblock.fs_bsize) *
468*5326Smckusic 			    sblock.fs_frag;
4695098Smckusic 		}
4705098Smckusic 		for (d = 0; d < dmin; d++)
4715098Smckusic 			clrbit(cgrp.cg_free, d);
472*5326Smckusic 		for (; (d + sblock.fs_frag) <= dmax - dbase; d += sblock.fs_frag) {
4735098Smckusic 			j = 0;
474*5326Smckusic 			for (i = 0; i < sblock.fs_frag; i++) {
4755098Smckusic 				if (!isset(bmap, dbase+d+i)) {
4765098Smckusic 					setbit(cgrp.cg_free, d+i);
4775098Smckusic 					j++;
4785098Smckusic 				} else
4795098Smckusic 					clrbit(cgrp.cg_free, d+i);
4805098Smckusic 			}
481*5326Smckusic 			if (j == sblock.fs_frag) {
4825098Smckusic 				cgrp.cg_cs.cs_nbfree++;
483*5326Smckusic 				s = d * NSPF(&sblock);
4845098Smckusic 				cgrp.cg_b[s/sblock.fs_spc]
4855098Smckusic 				  [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++;
4865098Smckusic 			} else if (j > 0) {
4875098Smckusic 				cgrp.cg_cs.cs_nffree += j;
4885098Smckusic 				blk = ((cgrp.cg_free[d / NBBY] >> (d % NBBY)) &
489*5326Smckusic 				       (0xff >> (NBBY - sblock.fs_frag)));
490*5326Smckusic 				fragacct(&sblock, blk, cgrp.cg_frsum, 1);
4915098Smckusic 			}
4925098Smckusic 		}
4935098Smckusic 		for (j = d; d < dmax - dbase; d++) {
4945098Smckusic 			if (!isset(bmap, dbase+d)) {
4955098Smckusic 				setbit(cgrp.cg_free, d);
4965098Smckusic 				cgrp.cg_cs.cs_nffree++;
4975098Smckusic 			} else
4985098Smckusic 				clrbit(cgrp.cg_free, d);
4995098Smckusic 		}
5005098Smckusic 		if (j != d) {
5015098Smckusic 			blk = ((cgrp.cg_free[j / NBBY] >> (j % NBBY)) &
502*5326Smckusic 			       (0xff >> (NBBY - sblock.fs_frag)));
503*5326Smckusic 			fragacct(&sblock, blk, cgrp.cg_frsum, 1);
5045098Smckusic 		}
505*5326Smckusic 		for (; d < MAXBPG(&sblock); d++)
5065098Smckusic 			clrbit(cgrp.cg_free, d);
5075098Smckusic 		sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
5085098Smckusic 		sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
5095098Smckusic 		sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
5105098Smckusic 		sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
5115098Smckusic 		*cs = cgrp.cg_cs;
512*5326Smckusic 		bwrite(fsbtodb(&sblock, cgtod(c, &sblock)), &cgrp,
513*5326Smckusic 			sblock.fs_cgsize);
5145098Smckusic 	}
515*5326Smckusic 	for (i = 0; i < howmany(sblock.fs_cssize, sblock.fs_bsize); i++) {
516*5326Smckusic 		bwrite(fsbtodb(&sblock,
517*5326Smckusic 		    sblock.fs_csaddr + (i * sblock.fs_frag)),
518*5326Smckusic 		    (char *)sblock.fs_csp[i], sblock.fs_bsize);
5195098Smckusic 	}
5205098Smckusic 	sblock.fs_ronly = 0;
5215098Smckusic 	sblock.fs_fmod = 0;
522*5326Smckusic 	bwrite(SBLOCK, (char *)&sblock, MAXBSIZE);
5235098Smckusic }
5245098Smckusic 
5255098Smckusic /*
5265098Smckusic  * update the frsum fields to reflect addition or deletion
5275098Smckusic  * of some frags
5285098Smckusic  */
529*5326Smckusic fragacct(fs, fragmap, fraglist, cnt)
530*5326Smckusic 	struct fs *fs;
5315098Smckusic 	int fragmap;
5325098Smckusic 	long fraglist[];
5335098Smckusic 	int cnt;
5345098Smckusic {
5355098Smckusic 	int inblk;
5365098Smckusic 	register int field, subfield;
5375098Smckusic 	register int siz, pos;
5385098Smckusic 
539*5326Smckusic 	inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
5405098Smckusic 	fragmap <<= 1;
541*5326Smckusic 	for (siz = 1; siz < fs->fs_frag; siz++) {
5425098Smckusic 		if (((1 << siz) & inblk) == 0)
5435098Smckusic 			continue;
5445098Smckusic 		field = around[siz];
5455098Smckusic 		subfield = inside[siz];
546*5326Smckusic 		for (pos = siz; pos <= fs->fs_frag; pos++) {
5475098Smckusic 			if ((fragmap & field) == subfield) {
5485098Smckusic 				fraglist[siz] += cnt;
5495098Smckusic 				pos += siz;
5505098Smckusic 				field <<= siz;
5515098Smckusic 				subfield <<= siz;
5525098Smckusic 			}
5535098Smckusic 			field <<= 1;
5545098Smckusic 			subfield <<= 1;
5555098Smckusic 		}
5565098Smckusic 	}
5575098Smckusic }
5585098Smckusic 
559*5326Smckusic getsb(fs, file)
560*5326Smckusic 	register struct fs *fs;
561*5326Smckusic 	char *file;
562*5326Smckusic {
563*5326Smckusic 	int i;
564*5326Smckusic 
565*5326Smckusic 	if (bread(SBLOCK, fs, MAXBSIZE)) {
566*5326Smckusic 		printf("bad super block");
567*5326Smckusic 		perror(file);
568*5326Smckusic 		nerror |= 04;
569*5326Smckusic 		return;
570*5326Smckusic 	}
571*5326Smckusic 	if (fs->fs_magic != FS_MAGIC) {
572*5326Smckusic 		printf("%s: bad magic number\n", file);
573*5326Smckusic 		nerror |= 04;
574*5326Smckusic 		return;
575*5326Smckusic 	}
576*5326Smckusic 	for (i = 0; i < howmany(fs->fs_cssize, fs->fs_bsize); i++) {
577*5326Smckusic 		fs->fs_csp[i] = (struct csum *)calloc(1, fs->fs_bsize);
578*5326Smckusic 		bread(fsbtodb(fs, fs->fs_csaddr + (i * fs->fs_frag)),
579*5326Smckusic 		      (char *)fs->fs_csp[i], fs->fs_bsize);
580*5326Smckusic 	}
581*5326Smckusic }
582*5326Smckusic 
5835098Smckusic bwrite(blk, buf, size)
5845098Smckusic 	char *buf;
5855098Smckusic 	daddr_t blk;
5865098Smckusic 	register size;
5875098Smckusic {
588*5326Smckusic 	if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
5895098Smckusic 		perror("FS SEEK");
5905098Smckusic 		return(1);
5915098Smckusic 	}
5925098Smckusic 	if (write(fi, buf, size) != size) {
5935098Smckusic 		perror("FS WRITE");
5945098Smckusic 		return(1);
5955098Smckusic 	}
596*5326Smckusic 	return (0);
5975098Smckusic }
5985098Smckusic 
5994240Smckusick bread(bno, buf, cnt)
6004410Smckusic 	daddr_t bno;
6014410Smckusic 	char *buf;
6024240Smckusick {
6034240Smckusick 	register i;
6044240Smckusick 
605*5326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
6064240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
6075098Smckusic 		if (sflg) {
6085098Smckusic 			printf("No Update\n");
6095098Smckusic 			sflg = 0;
6105098Smckusic 		}
611*5326Smckusic 		for(i=0; i<sblock.fs_bsize; i++)
6124240Smckusick 			buf[i] = 0;
613*5326Smckusic 		return (1);
6144240Smckusick 	}
615*5326Smckusic 	return (0);
6164240Smckusick }
617*5326Smckusic 
618*5326Smckusic /*
619*5326Smckusic  * block operations
620*5326Smckusic  */
621*5326Smckusic 
622*5326Smckusic isblock(fs, cp, h)
623*5326Smckusic 	struct fs *fs;
624*5326Smckusic 	unsigned char *cp;
625*5326Smckusic 	int h;
626*5326Smckusic {
627*5326Smckusic 	unsigned char mask;
628*5326Smckusic 
629*5326Smckusic 	switch (fs->fs_frag) {
630*5326Smckusic 	case 8:
631*5326Smckusic 		return (cp[h] == 0xff);
632*5326Smckusic 	case 4:
633*5326Smckusic 		mask = 0x0f << ((h & 0x1) << 2);
634*5326Smckusic 		return ((cp[h >> 1] & mask) == mask);
635*5326Smckusic 	case 2:
636*5326Smckusic 		mask = 0x03 << ((h & 0x3) << 1);
637*5326Smckusic 		return ((cp[h >> 2] & mask) == mask);
638*5326Smckusic 	case 1:
639*5326Smckusic 		mask = 0x01 << (h & 0x7);
640*5326Smckusic 		return ((cp[h >> 3] & mask) == mask);
641*5326Smckusic 	default:
642*5326Smckusic 		fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
643*5326Smckusic 		return;
644*5326Smckusic 	}
645*5326Smckusic }
646*5326Smckusic 
647*5326Smckusic setblock(fs, cp, h)
648*5326Smckusic 	struct fs *fs;
649*5326Smckusic 	unsigned char *cp;
650*5326Smckusic 	int h;
651*5326Smckusic {
652*5326Smckusic 	switch (fs->fs_frag) {
653*5326Smckusic 	case 8:
654*5326Smckusic 		cp[h] = 0xff;
655*5326Smckusic 		return;
656*5326Smckusic 	case 4:
657*5326Smckusic 		cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
658*5326Smckusic 		return;
659*5326Smckusic 	case 2:
660*5326Smckusic 		cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
661*5326Smckusic 		return;
662*5326Smckusic 	case 1:
663*5326Smckusic 		cp[h >> 3] |= (0x01 << (h & 0x7));
664*5326Smckusic 		return;
665*5326Smckusic 	default:
666*5326Smckusic 		fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
667*5326Smckusic 		return;
668*5326Smckusic 	}
669*5326Smckusic }
670