xref: /csrg-svn/sbin/icheck/icheck.c (revision 4773)
1*4773Smckusic /*###1 [lint] static variable sccsid unused%%%*/
2*4773Smckusic /*###1 [lint] sccsid defined( icheck.c(1) ), but never used%%%*/
3*4773Smckusic static	char *sccsid = "@(#)icheck.c	1.7 (Berkeley) 11/07/81";
44410Smckusic 
54240Smckusick /*
64240Smckusick  * icheck
74240Smckusick  */
84240Smckusick #define	NB	500
94240Smckusick #define	BITS	8
104240Smckusick #define	MAXFN	500
114240Smckusick 
124240Smckusick #ifndef STANDALONE
134240Smckusick #include <stdio.h>
144240Smckusick #endif
154240Smckusick #include "../h/param.h"
164240Smckusick #include "../h/inode.h"
174240Smckusick #include "../h/fs.h"
184240Smckusick 
194240Smckusick union {
204240Smckusick 	struct	fs sb;
214240Smckusick 	char pad[BSIZE];
224240Smckusick } sbun;
234240Smckusick #define	sblock sbun.sb
244240Smckusick 
254240Smckusick union {
264240Smckusick 	struct	cg cg;
274240Smckusick 	char pad[BSIZE];
284240Smckusick } cgun;
294240Smckusick #define	cgrp cgun.cg
304240Smckusick 
314240Smckusick struct	dinode	itab[MAXIPG];
324240Smckusick daddr_t	blist[NB];
334240Smckusick char	*bmap;
344240Smckusick 
354240Smckusick int	mflg;
364240Smckusick int	dflg;
374240Smckusick int	fi;
384240Smckusick ino_t	ino;
394240Smckusick int	cginit;
404240Smckusick 
414240Smckusick ino_t	nrfile;
424240Smckusick ino_t	ndfile;
434240Smckusick ino_t	nbfile;
444240Smckusick ino_t	ncfile;
454240Smckusick ino_t	nmcfile;
464240Smckusick 
474240Smckusick daddr_t	nblock;
484240Smckusick daddr_t	nfrag;
494240Smckusick daddr_t	nindir;
504240Smckusick daddr_t	niindir;
514240Smckusick 
524240Smckusick daddr_t	nffree;
534240Smckusick daddr_t	nbfree;
544240Smckusick 
554240Smckusick daddr_t	ndup;
564240Smckusick 
574240Smckusick int	nerror;
584240Smckusick 
594240Smckusick long	atol();
604240Smckusick daddr_t	alloc();
614240Smckusick #ifndef STANDALONE
624240Smckusick char	*malloc();
634240Smckusick #endif
644240Smckusick 
654240Smckusick main(argc, argv)
664240Smckusick char *argv[];
674240Smckusick {
684240Smckusick 	register i;
694240Smckusick 	long n;
704240Smckusick 
714240Smckusick 	blist[0] = -1;
724240Smckusick #ifndef STANDALONE
734240Smckusick 	while (--argc) {
744240Smckusick 		argv++;
754240Smckusick 		if (**argv=='-')
764240Smckusick 		switch ((*argv)[1]) {
774240Smckusick 		case 'd':
784240Smckusick 			dflg++;
794240Smckusick 			continue;
804240Smckusick 
814240Smckusick 		case 'm':
824240Smckusick 			mflg++;
834240Smckusick 			continue;
844240Smckusick 
854240Smckusick 		case 'b':
864240Smckusick 			for(i=0; i<NB; i++) {
874240Smckusick 				n = atol(argv[1]);
884240Smckusick 				if(n == 0)
894240Smckusick 					break;
904240Smckusick 				blist[i] = n;
914240Smckusick 				argv++;
924240Smckusick 				argc--;
934240Smckusick 			}
944240Smckusick 			blist[i] = -1;
954240Smckusick 			continue;
964240Smckusick 
974240Smckusick 		default:
984240Smckusick 			printf("Bad flag\n");
994240Smckusick 		}
1004240Smckusick 		check(*argv);
1014240Smckusick 	}
1024240Smckusick #else
1034240Smckusick 	{
1044240Smckusick 		static char fname[128];
1054240Smckusick 
1064240Smckusick 		printf("File: ");
1074240Smckusick 		gets(fname);
1084240Smckusick 		check(fname);
1094240Smckusick 	}
1104240Smckusick #endif
1114240Smckusick 	return(nerror);
1124240Smckusick }
1134240Smckusick 
1144240Smckusick check(file)
1154240Smckusick char *file;
1164240Smckusick {
1174240Smckusick 	register i, j, c;
1184240Smckusick 	daddr_t d, cgd, cbase, b;
1194240Smckusick 	long n;
1204240Smckusick 
121*4773Smckusic 	fi = open(file, 0);
1224240Smckusick 	if (fi < 0) {
1234240Smckusick 		printf("cannot open %s\n", file);
1244240Smckusick 		nerror |= 04;
1254240Smckusick 		return;
1264240Smckusick 	}
1274240Smckusick 	printf("%s:\n", file);
1284240Smckusick 	nrfile = 0;
1294240Smckusick 	ndfile = 0;
1304240Smckusick 	ncfile = 0;
1314240Smckusick 	nbfile = 0;
1324240Smckusick 	nmcfile = 0;
1334240Smckusick 
1344240Smckusick 	nblock = 0;
1354240Smckusick 	nfrag = 0;
1364240Smckusick 	nindir = 0;
1374240Smckusick 	niindir = 0;
1384240Smckusick 
1394240Smckusick 	ndup = 0;
1404240Smckusick #ifndef STANDALONE
1414240Smckusick 	sync();
1424240Smckusick #endif
1434240Smckusick 	bread(SBLOCK, (char *)&sblock, BSIZE);
1444240Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
1454240Smckusick 		printf("%s: bad magic number\n", file);
1464240Smckusick 		nerror |= 04;
1474240Smckusick 		return;
1484240Smckusick 	}
1494654Smckusic 	for (n = 0; n < howmany(cssize(&sblock), BSIZE); n++) {
150*4773Smckusic /*###148 [lint] calloc value declared inconsistently llib-lc(58) :: icheck.c(148)%%%*/
151*4773Smckusic /*###148 [lint] calloc value used inconsistently llib-lc(58) :: icheck.c(148)%%%*/
1524654Smckusic 		sblock.fs_csp[n] = (struct csum *)calloc(1, BSIZE);
1534654Smckusic 		bread(csaddr(&sblock) + (n * FRAG),
1544654Smckusic 		      (char *)sblock.fs_csp[n], BSIZE);
1554654Smckusic 	}
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 	}
1674240Smckusick 	ino = 0;
1684240Smckusick 	cginit = 1;
1694240Smckusick 	if(!dflg) {
1704240Smckusick 		for (i=0; i<(unsigned)n; i++)
1714240Smckusick 			bmap[i] = 0;
1724240Smckusick 		for (c=0; c < sblock.fs_ncg; c++) {
1734240Smckusick 			cgd = cgtod(c, &sblock);
1744410Smckusic 			for (d = cgbase(c, &sblock); d < cgd; d += FRAG)
1754429Smckusic 				chk(d, "badcg", BSIZE);
1764240Smckusick 			d = cgimin(c, &sblock);
1774240Smckusick 			while (cgd < d) {
1784429Smckusic 				chk(cgd, "cg", BSIZE);
1794410Smckusic 				cgd += FRAG;
1804240Smckusick 			}
1814240Smckusick 			d = cgdmin(c, &sblock);
1824410Smckusic 			for (; cgd < d; cgd += FRAG)
1834429Smckusic 				chk(cgd, "inode", BSIZE);
1844240Smckusick 			if (c == 0) {
1854410Smckusic 				d += howmany(cssize(&sblock), FSIZE);
1864410Smckusic 				for (; cgd < d; cgd += FRAG)
1874429Smckusic 					chk(cgd, "csum", BSIZE);
1884240Smckusick 			}
1894240Smckusick 		}
1904240Smckusick 	}
1914240Smckusick 	cginit = 0;
1924240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1934240Smckusick 		bread(cgimin(c,&sblock), (char *)itab,
1944240Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1954240Smckusick 		for (j=0; j < sblock.fs_ipg; j++) {
1964240Smckusick 			pass1(&itab[j]);
1974240Smckusick 			ino++;
1984240Smckusick 		}
1994240Smckusick 	}
2004240Smckusick 	ino = 0;
2014240Smckusick #ifndef STANDALONE
2024240Smckusick 	sync();
2034240Smckusick #endif
2044240Smckusick 	bread(SBLOCK, (char *)&sblock, sizeof(sblock));
2054240Smckusick 	nffree = 0;
2064240Smckusick 	nbfree = 0;
2074240Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
2084240Smckusick 		cbase = cgbase(c,&sblock);
2094240Smckusick 		bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize);
2104240Smckusick 		for (b = 0; b < sblock.fs_fpg; b += FRAG) {
2114240Smckusick 			if (isblock(cgrp.cg_free, b / FRAG)) {
2124240Smckusick 				nbfree++;
2134429Smckusic 				chk(cbase+b, "block", BSIZE);
2144240Smckusick 			} else {
2154240Smckusick 				for (d = 0; d < FRAG; d++)
2164240Smckusick 					if (isset(cgrp.cg_free, b+d)) {
2174429Smckusic 						chk(cbase+b+d, "frag", FSIZE);
2184240Smckusick 						nffree++;
2194240Smckusick 					}
2204240Smckusick 			}
2214240Smckusick 		}
2224240Smckusick 	}
2234240Smckusick 	close(fi);
2244240Smckusick #ifndef STANDALONE
2254240Smckusick 	if (bmap)
2264240Smckusick 		free(bmap);
2274240Smckusick #endif
2284240Smckusick 
2294240Smckusick 	i = nrfile + ndfile + ncfile + nbfile + nmcfile;
2304240Smckusick #ifndef STANDALONE
2314240Smckusick 	printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2324240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2334240Smckusick #else
2344240Smckusick 	printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
2354240Smckusick 		i, nrfile, ndfile, nbfile, ncfile, nmcfile);
2364240Smckusick #endif
2374429Smckusic 	n = (nblock + nindir + niindir) * FRAG + nfrag;
2384240Smckusick #ifdef STANDALONE
2394240Smckusick 	printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2404240Smckusick 		n, nindir, niindir, nblock, nfrag);
2414429Smckusic 	printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
2424240Smckusick 	    nbfree, nffree);
2434240Smckusick #else
2444240Smckusick 	printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
2454240Smckusick 		n, nindir, niindir, nblock, nfrag);
2464429Smckusic 	printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
2474240Smckusick 	    nbfree, nffree);
2484240Smckusick #endif
2494240Smckusick 	if(!dflg) {
2504240Smckusick 		n = 0;
2514410Smckusic 		for (d = 0; d < sblock.fs_size; d++)
2524429Smckusic 			if(!duped(d, FSIZE)) {
2534240Smckusick 				if(mflg)
2544240Smckusick 					printf("%ld missing\n", d);
2554240Smckusick 				n++;
2564240Smckusick 			}
2574240Smckusick 		printf("missing%5ld\n", n);
2584240Smckusick 	}
2594240Smckusick }
2604240Smckusick 
2614240Smckusick pass1(ip)
2624410Smckusic 	register struct dinode *ip;
2634240Smckusick {
2644429Smckusic 	daddr_t ind1[NINDIR];
2654429Smckusic 	daddr_t ind2[NINDIR];
2664429Smckusic 	daddr_t db, ib;
2674429Smckusic 	register int i, j, k, siz;
2684240Smckusick 
2694240Smckusick 	i = ip->di_mode & IFMT;
2704240Smckusick 	if(i == 0) {
2714240Smckusick 		sblock.fs_nifree++;
2724240Smckusick 		return;
2734240Smckusick 	}
2744240Smckusick 	switch (i) {
2754240Smckusick 	case IFCHR:
2764240Smckusick 		ncfile++;
2774240Smckusick 		return;
2784240Smckusick 	case IFBLK:
2794240Smckusick 		nbfile++;
2804240Smckusick 		return;
2814240Smckusick 	case IFDIR:
2824240Smckusick 		ndfile++;
2834240Smckusick 		break;
2844240Smckusick 	case IFREG:
2854240Smckusick 		nrfile++;
2864240Smckusick 		break;
2874240Smckusick 	default:
2884240Smckusick 		printf("bad mode %u\n", ino);
2894240Smckusick 		return;
2904240Smckusick 	}
2914410Smckusic 	for (i = 0; i < NDADDR; i++) {
2924410Smckusic 		db = ip->di_db[i];
2934410Smckusic 		if (db == 0)
2944240Smckusick 			continue;
2954429Smckusic 		siz = dblksize(ip, i);
2964429Smckusic 		chk(db, "data (block)", siz);
2974429Smckusic 		if (siz == BSIZE)
2984429Smckusic 			nblock++;
2994429Smckusic 		else
3004429Smckusic 			nfrag += howmany(siz, FSIZE);
3014240Smckusick 	}
3024410Smckusic 	for(i = 0; i < NIADDR; i++) {
3034410Smckusic 		ib = ip->di_ib[i];
3044410Smckusic 		if(ib == 0)
3054240Smckusick 			continue;
3064429Smckusic 		if (chk(ib, "1st indirect", BSIZE))
3074410Smckusic 			continue;
3084429Smckusic 		bread(ib, (char *)ind1, BSIZE);
3094240Smckusick 		nindir++;
3104410Smckusic 		for (j = 0; j < NINDIR; j++) {
3114410Smckusic 			ib = ind1[j];
3124410Smckusic 			if (ib == 0)
3134240Smckusick 				continue;
3144410Smckusic 			if (i == 0) {
3154429Smckusic 				siz = dblksize(ip, NDADDR + j);
3164429Smckusic 				chk(ib, "data (large)", siz);
3174429Smckusic 				if (siz == BSIZE)
3184429Smckusic 					nblock++;
3194429Smckusic 				else
3204429Smckusic 					nfrag += howmany(siz, FSIZE);
3214240Smckusick 				continue;
3224240Smckusick 			}
3234429Smckusic 			if (chk(ib, "2nd indirect", BSIZE))
3244410Smckusic 				continue;
3254429Smckusic 			bread(ib, (char *)ind2, BSIZE);
3264240Smckusick 			niindir++;
3274410Smckusic 			for (k = 0; k < NINDIR; k++) {
3284410Smckusic 				ib = ind2[k];
3294410Smckusic 				if (ib == 0)
3304240Smckusick 					continue;
3314429Smckusic 				siz = dblksize(ip,
3324429Smckusic 				    NDADDR + NINDIR * (i + j) + k);
3334429Smckusic 				chk(ib, "data (huge)", siz);
3344429Smckusic 				if (siz == BSIZE)
3354429Smckusic 					nblock++;
3364429Smckusic 				else
3374429Smckusic 					nfrag += howmany(siz, FSIZE);
3384240Smckusick 			}
3394240Smckusick 		}
3404240Smckusick 	}
3414240Smckusick }
3424240Smckusick 
3434429Smckusic chk(bno, s, size)
3444410Smckusic 	daddr_t bno;
3454410Smckusic 	char *s;
3464429Smckusic 	int size;
3474240Smckusick {
3484240Smckusick 	register n, cg;
3494240Smckusick 
3504240Smckusick 	cg = dtog(bno, &sblock);
3514429Smckusic 	if (cginit==0 &&
3524429Smckusic 	    bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) {
3534240Smckusick 		printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
3544240Smckusick 		return(1);
3554240Smckusick 	}
3564429Smckusic 	if (size == BSIZE) {
3574429Smckusic 		if (duped(bno, size)) {
3584429Smckusic 			printf("%ld dup block; inode=%u, class=%s\n",
3594429Smckusic 			    bno, ino, s);
3604429Smckusic 			ndup += FRAG;
3614429Smckusic 		}
3624429Smckusic 	} else {
3634429Smckusic 		for (n = 0; n < size / FSIZE; n++) {
3644429Smckusic 			if (duped(bno + n, FSIZE)) {
3654429Smckusic 				printf("%ld dup frag; inode=%u, class=%s\n",
3664429Smckusic 				    bno, ino, s);
3674429Smckusic 				ndup++;
3684429Smckusic 			}
3694429Smckusic 		}
3704240Smckusick 	}
3714240Smckusick 	for (n=0; blist[n] != -1; n++)
3724240Smckusick 		if (bno == blist[n])
3734240Smckusick 			printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
3744240Smckusick 	return(0);
3754240Smckusick }
3764240Smckusick 
3774429Smckusic duped(bno, size)
3784410Smckusic 	daddr_t bno;
3794429Smckusic 	int size;
3804240Smckusick {
3814240Smckusick 	if(dflg)
3824240Smckusick 		return(0);
3834429Smckusic 	if (size != FSIZE && size != BSIZE)
3844429Smckusic 		printf("bad size %d to duped\n", size);
3854429Smckusic 	if (size == FSIZE) {
3864410Smckusic 		if (isset(bmap, bno))
3874410Smckusic 			return(1);
3884410Smckusic 		setbit(bmap, bno);
3894410Smckusic 		return (0);
3904410Smckusic 	}
3914410Smckusic 	if (bno % FRAG != 0)
3924410Smckusic 		printf("bad bno %d to duped\n", bno);
3934410Smckusic 	if (isblock(bmap, bno/FRAG))
3944410Smckusic 		return (1);
3954410Smckusic 	setblock(bmap, bno/FRAG);
3964240Smckusick 	return(0);
3974240Smckusick }
3984240Smckusick 
3994240Smckusick bread(bno, buf, cnt)
4004410Smckusic 	daddr_t bno;
4014410Smckusic 	char *buf;
4024240Smckusick {
4034240Smckusick 	register i;
4044240Smckusick 
4054240Smckusick 	lseek(fi, bno*FSIZE, 0);
406*4773Smckusic /*###402 [lint] lseek value declared inconsistently llib-lc(31) :: icheck.c(402)%%%*/
4074240Smckusick 	if ((i = read(fi, buf, cnt)) != cnt) {
4084240Smckusick 		for(i=0; i<BSIZE; i++)
4094240Smckusick 			buf[i] = 0;
4104240Smckusick 	}
4114240Smckusick }
412