xref: /csrg-svn/old/dcheck/dcheck.c (revision 4253)
1*4253Smckusic static	char *sccsid = "@(#)dcheck.c	1.2 (Berkeley) 08/28/81";
24238Smckusick /*
34238Smckusick  * dcheck - check directory consistency
44238Smckusick  */
54238Smckusick #define	NB	10
64238Smckusick #define	NDIR	(BSIZE/sizeof(struct direct))
74238Smckusick 
84238Smckusick #include <stdio.h>
94238Smckusick #include "../h/param.h"
104238Smckusick #include "../h/inode.h"
114238Smckusick #include "../h/dir.h"
124238Smckusick #include "../h/fs.h"
134238Smckusick 
144238Smckusick union {
154238Smckusick 	struct	fs fs;
164238Smckusick 	char pad[BSIZE];
174238Smckusick } fsun;
184238Smckusick #define	sblock	fsun.fs
194238Smckusick 
204238Smckusick struct	dinode	itab[MAXIPG];
21*4253Smckusic struct	dinode	*gip;
224238Smckusick ino_t	ilist[NB];
234238Smckusick 
244238Smckusick int	fi;
254238Smckusick ino_t	ino;
264238Smckusick ino_t	*ecount;
274238Smckusick int	headpr;
284238Smckusick int	nfiles;
294238Smckusick 
304238Smckusick int	nerror;
314238Smckusick daddr_t	bmap();
324238Smckusick long	atol();
334238Smckusick char	*malloc();
344238Smckusick 
354238Smckusick main(argc, argv)
364238Smckusick char *argv[];
374238Smckusick {
384238Smckusick 	register i;
394238Smckusick 	long n;
404238Smckusick 
414238Smckusick 	while (--argc) {
424238Smckusick 		argv++;
434238Smckusick 		if (**argv=='-')
444238Smckusick 		switch ((*argv)[1]) {
454238Smckusick 
464238Smckusick 		case 'i':
474238Smckusick 			for(i=0; i<NB; i++) {
484238Smckusick 				n = atol(argv[1]);
494238Smckusick 				if(n == 0)
504238Smckusick 					break;
514238Smckusick 				ilist[i] = n;
524238Smckusick 				argv++;
534238Smckusick 				argc--;
544238Smckusick 			}
554238Smckusick 			ilist[i] = 0;
564238Smckusick 			continue;
574238Smckusick 
584238Smckusick 		default:
594238Smckusick 			printf("Bad flag %c\n", (*argv)[1]);
604238Smckusick 			nerror++;
614238Smckusick 		}
624238Smckusick 		check(*argv);
634238Smckusick 	}
644238Smckusick 	return(nerror);
654238Smckusick }
664238Smckusick 
674238Smckusick check(file)
684238Smckusick char *file;
694238Smckusick {
704238Smckusick 	register i, j, c;
714238Smckusick 
724238Smckusick 	fi = open(file, 0);
734238Smckusick 	if(fi < 0) {
744238Smckusick 		printf("cannot open %s\n", file);
754238Smckusick 		nerror++;
764238Smckusick 		return;
774238Smckusick 	}
784238Smckusick 	headpr = 0;
794238Smckusick 	printf("%s:\n", file);
804238Smckusick 	sync();
814238Smckusick 	bread(SBLOCK, (char *)&sblock, BSIZE);
824238Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
834238Smckusick 		printf("%s: not a file system\n", file);
844238Smckusick 		nerror++;
854238Smckusick 		return;
864238Smckusick 	}
874238Smckusick 	nfiles = sblock.fs_ipg * sblock.fs_ncg;
884238Smckusick 	if (nfiles > 65535) {
894238Smckusick 		printf("%s: preposterous number of files\n", file);
904238Smckusick 		nerror++;
914238Smckusick 		return;
924238Smckusick 	}
934238Smckusick 	ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
944238Smckusick 	if (ecount == 0) {
954238Smckusick 		printf("%s: not enough core for %d files\n", file, nfiles);
964238Smckusick 		exit(04);
974238Smckusick 	}
984238Smckusick 	for (i = 0; i<=nfiles; i++)
994238Smckusick 		ecount[i] = 0;
1004238Smckusick 	ino = 0;
1014238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1024238Smckusick 		bread(cgimin(c, &sblock), (char *)itab,
1034238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1044238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1054238Smckusick 			pass1(&itab[j]);
1064238Smckusick 			ino++;
1074238Smckusick 		}
1084238Smckusick 	}
1094238Smckusick 	ino = 0;
1104238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1114238Smckusick 		bread(cgimin(c, &sblock), (char *)itab,
1124238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1134238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1144238Smckusick 			pass2(&itab[j]);
1154238Smckusick 			ino++;
1164238Smckusick 		}
1174238Smckusick 	}
1184238Smckusick 	free(ecount);
1194238Smckusick }
1204238Smckusick 
1214238Smckusick pass1(ip)
1224238Smckusick register struct dinode *ip;
1234238Smckusick {
1244238Smckusick 	struct direct dbuf[NDIR];
1254238Smckusick 	long doff;
1264238Smckusick 	struct direct *dp;
1274238Smckusick 	register i, j;
1284238Smckusick 	int k;
1294238Smckusick 	daddr_t d;
1304238Smckusick 	ino_t kno;
1314238Smckusick 
1324238Smckusick 	if((ip->di_mode&IFMT) != IFDIR)
1334238Smckusick 		return;
134*4253Smckusic 	gip = ip;
1354238Smckusick 	doff = 0;
1364238Smckusick 	for(i=0;; i++) {
1374238Smckusick 		if(doff >= ip->di_size)
1384238Smckusick 			break;
1394238Smckusick 		d = bmap(i);
1404238Smckusick 		if(d == 0)
1414238Smckusick 			break;
1424238Smckusick 		bread(d, (char *)dbuf, BSIZE);
1434238Smckusick 		for(j=0; j<NDIR; j++) {
1444238Smckusick 			if(doff >= ip->di_size)
1454238Smckusick 				break;
1464238Smckusick 			doff += sizeof(struct direct);
1474238Smckusick 			dp = &dbuf[j];
1484238Smckusick 			kno = dp->d_ino;
1494238Smckusick 			if(kno == 0)
1504238Smckusick 				continue;
1514238Smckusick 			if(kno > nfiles || kno < ROOTINO) {
1524238Smckusick 				printf("%d bad; %d/%.*s\n",
1534238Smckusick 				    kno, ino, DIRSIZ, dp->d_name);
1544238Smckusick 				nerror++;
1554238Smckusick 				continue;
1564238Smckusick 			}
1574238Smckusick 			for (k=0; ilist[k] != 0; k++)
1584238Smckusick 				if (ilist[k]==kno) {
1594238Smckusick 					printf("%d arg; %d/%.*s\n",
1604238Smckusick 					    kno, ino, DIRSIZ, dp->d_name);
1614238Smckusick 					nerror++;
1624238Smckusick 				}
1634238Smckusick 			ecount[kno]++;
1644238Smckusick 		}
1654238Smckusick 	}
1664238Smckusick }
1674238Smckusick 
1684238Smckusick pass2(ip)
1694238Smckusick register struct dinode *ip;
1704238Smckusick {
1714238Smckusick 	register i;
1724238Smckusick 
1734238Smckusick 	i = ino;
1744238Smckusick 	if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
1754238Smckusick 		return;
1764238Smckusick 	if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
1774238Smckusick 		return;
1784238Smckusick 	if (headpr==0) {
1794238Smckusick 		printf("     entries  link cnt\n");
1804238Smckusick 		headpr++;
1814238Smckusick 	}
1824238Smckusick 	printf("%u\t%d\t%d\n", ino,
1834238Smckusick 	    ecount[i], ip->di_nlink);
1844238Smckusick }
1854238Smckusick 
1864238Smckusick bread(bno, buf, cnt)
1874238Smckusick daddr_t bno;
1884238Smckusick char *buf;
1894238Smckusick {
1904238Smckusick 	register i;
1914238Smckusick 
1924238Smckusick 	lseek(fi, bno*FSIZE, 0);
1934238Smckusick 	if (read(fi, buf, cnt) != cnt) {
1944238Smckusick 		printf("read error %d\n", bno);
1954238Smckusick 		for(i=0; i<BSIZE; i++)
1964238Smckusick 			buf[i] = 0;
1974238Smckusick 	}
1984238Smckusick }
1994238Smckusick 
2004238Smckusick daddr_t
2014238Smckusick bmap(i)
2024238Smckusick {
2034238Smckusick 	daddr_t ibuf[NINDIR];
2044238Smckusick 
2054238Smckusick 	if(i < NDADDR)
206*4253Smckusic 		return(gip->di_db[i]);
2074238Smckusick 	i -= NDADDR;
2084238Smckusick 	if(i > NINDIR) {
2094238Smckusick 		printf("%u - huge directory\n", ino);
2104238Smckusick 		return((daddr_t)0);
2114238Smckusick 	}
212*4253Smckusic 	bread(gip->di_ib[i], (char *)ibuf, sizeof(ibuf));
2134238Smckusick 	return(ibuf[i]);
2144238Smckusick }
215