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