xref: /csrg-svn/old/dcheck/dcheck.c (revision 13550)
1*13550Ssam #ifndef lint
2*13550Ssam static	char *sccsid = "@(#)dcheck.c	2.4 (Berkeley) 07/01/83";
3*13550Ssam #endif
44238Smckusick /*
54238Smckusick  * dcheck - check directory consistency
64238Smckusick  */
74238Smckusick #define	NB	10
85348Smckusic #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
94238Smckusick 
106493Smckusick #include <sys/param.h>
116493Smckusick #include <sys/inode.h>
126493Smckusick #include <sys/fs.h>
13*13550Ssam #include <sys/dir.h>
145946Smckusic #include <stdio.h>
154238Smckusick 
164238Smckusick union {
174238Smckusick 	struct	fs fs;
185326Smckusic 	char pad[MAXBSIZE];
194238Smckusick } fsun;
204238Smckusick #define	sblock	fsun.fs
214238Smckusick 
225946Smckusic struct dirstuff {
235946Smckusic 	int loc;
245946Smckusic 	struct dinode *ip;
255946Smckusic 	char dbuf[MAXBSIZE];
265946Smckusic };
275946Smckusic 
284238Smckusick struct	dinode	itab[MAXIPG];
294253Smckusic struct	dinode	*gip;
304238Smckusick ino_t	ilist[NB];
314238Smckusick 
324238Smckusick int	fi;
334238Smckusick ino_t	ino;
344238Smckusick ino_t	*ecount;
354238Smckusick int	headpr;
364238Smckusick int	nfiles;
374238Smckusick 
384238Smckusick int	nerror;
394238Smckusick daddr_t	bmap();
404238Smckusick long	atol();
414238Smckusick char	*malloc();
424238Smckusick 
434238Smckusick main(argc, argv)
444238Smckusick char *argv[];
454238Smckusick {
464238Smckusick 	register i;
474238Smckusick 	long n;
484238Smckusick 
494238Smckusick 	while (--argc) {
504238Smckusick 		argv++;
514238Smckusick 		if (**argv=='-')
524238Smckusick 		switch ((*argv)[1]) {
534238Smckusick 
544238Smckusick 		case 'i':
554238Smckusick 			for(i=0; i<NB; i++) {
564238Smckusick 				n = atol(argv[1]);
574238Smckusick 				if(n == 0)
584238Smckusick 					break;
594238Smckusick 				ilist[i] = n;
604238Smckusick 				argv++;
614238Smckusick 				argc--;
624238Smckusick 			}
634238Smckusick 			ilist[i] = 0;
644238Smckusick 			continue;
654238Smckusick 
664238Smckusick 		default:
674238Smckusick 			printf("Bad flag %c\n", (*argv)[1]);
684238Smckusick 			nerror++;
694238Smckusick 		}
704238Smckusick 		check(*argv);
714238Smckusick 	}
724238Smckusick 	return(nerror);
734238Smckusick }
744238Smckusick 
754238Smckusick check(file)
764238Smckusick char *file;
774238Smckusick {
784238Smckusick 	register i, j, c;
794238Smckusick 
804238Smckusick 	fi = open(file, 0);
814238Smckusick 	if(fi < 0) {
824238Smckusick 		printf("cannot open %s\n", file);
834238Smckusick 		nerror++;
844238Smckusick 		return;
854238Smckusick 	}
864238Smckusick 	headpr = 0;
874238Smckusick 	printf("%s:\n", file);
884238Smckusick 	sync();
895348Smckusic 	bread(SBLOCK, (char *)&sblock, SBSIZE);
904238Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
914238Smckusick 		printf("%s: not a file system\n", file);
924238Smckusick 		nerror++;
934238Smckusick 		return;
944238Smckusick 	}
954238Smckusick 	nfiles = sblock.fs_ipg * sblock.fs_ncg;
964238Smckusick 	ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
974238Smckusick 	if (ecount == 0) {
984238Smckusick 		printf("%s: not enough core for %d files\n", file, nfiles);
994238Smckusick 		exit(04);
1004238Smckusick 	}
1014238Smckusick 	for (i = 0; i<=nfiles; i++)
1024238Smckusick 		ecount[i] = 0;
1034238Smckusick 	ino = 0;
1044238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1055379Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
1064238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1074238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1084238Smckusick 			pass1(&itab[j]);
1094238Smckusick 			ino++;
1104238Smckusick 		}
1114238Smckusick 	}
1124238Smckusick 	ino = 0;
1134238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1145379Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
1154238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1164238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1174238Smckusick 			pass2(&itab[j]);
1184238Smckusick 			ino++;
1194238Smckusick 		}
1204238Smckusick 	}
1214238Smckusick 	free(ecount);
1224238Smckusick }
1234238Smckusick 
1244238Smckusick pass1(ip)
1255946Smckusic 	register struct dinode *ip;
1264238Smckusick {
1275946Smckusic 	register struct direct *dp;
1285946Smckusic 	struct dirstuff dirp;
1294238Smckusick 	int k;
1304238Smckusick 
1314238Smckusick 	if((ip->di_mode&IFMT) != IFDIR)
1324238Smckusick 		return;
1335946Smckusic 	dirp.loc = 0;
1345946Smckusic 	dirp.ip = ip;
1354253Smckusic 	gip = ip;
1365946Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
1375946Smckusic 		if(dp->d_ino == 0)
1385946Smckusic 			continue;
1395946Smckusic 		if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
1405946Smckusic 			printf("%d bad; %d/%s\n",
1415946Smckusic 			    dp->d_ino, ino, dp->d_name);
1425946Smckusic 			nerror++;
1435946Smckusic 			continue;
1445946Smckusic 		}
1455946Smckusic 		for (k = 0; ilist[k] != 0; k++)
1465946Smckusic 			if (ilist[k] == dp->d_ino) {
1475946Smckusic 				printf("%d arg; %d/%s\n",
1485946Smckusic 				     dp->d_ino, ino, dp->d_name);
1494238Smckusick 				nerror++;
1504238Smckusick 			}
1515946Smckusic 		ecount[dp->d_ino]++;
1524238Smckusick 	}
1534238Smckusick }
1544238Smckusick 
1554238Smckusick pass2(ip)
1564238Smckusick register struct dinode *ip;
1574238Smckusick {
1584238Smckusick 	register i;
1594238Smckusick 
1604238Smckusick 	i = ino;
1614238Smckusick 	if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
1624238Smckusick 		return;
1634238Smckusick 	if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
1644238Smckusick 		return;
1654238Smckusick 	if (headpr==0) {
1664238Smckusick 		printf("     entries  link cnt\n");
1674238Smckusick 		headpr++;
1684238Smckusick 	}
1694238Smckusick 	printf("%u\t%d\t%d\n", ino,
1704238Smckusick 	    ecount[i], ip->di_nlink);
1714238Smckusick }
1724238Smckusick 
1735946Smckusic /*
1745946Smckusic  * get next entry in a directory.
1755946Smckusic  */
1765946Smckusic struct direct *
1775946Smckusic readdir(dirp)
1785946Smckusic 	register struct dirstuff *dirp;
1795946Smckusic {
1805946Smckusic 	register struct direct *dp;
1815946Smckusic 	daddr_t lbn, d;
1825946Smckusic 
1835946Smckusic 	for(;;) {
1845946Smckusic 		if (dirp->loc >= dirp->ip->di_size)
1855946Smckusic 			return NULL;
1865957Smckusic 		if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
1875946Smckusic 			d = bmap(lbn);
1885946Smckusic 			if(d == 0)
1895946Smckusic 				return NULL;
1905946Smckusic 			bread(fsbtodb(&sblock, d), dirp->dbuf,
1915946Smckusic 			    dblksize(&sblock, dirp->ip, lbn));
1925946Smckusic 		}
1935946Smckusic 		dp = (struct direct *)
1945957Smckusic 		    (dirp->dbuf + blkoff(&sblock, dirp->loc));
1955946Smckusic 		dirp->loc += dp->d_reclen;
1965946Smckusic 		if (dp->d_ino == 0)
1975946Smckusic 			continue;
1985946Smckusic 		return (dp);
1995946Smckusic 	}
2005946Smckusic }
2015946Smckusic 
2024238Smckusick bread(bno, buf, cnt)
2034238Smckusick daddr_t bno;
2044238Smckusick char *buf;
2054238Smckusick {
2064238Smckusick 	register i;
2074238Smckusick 
2085326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
2094238Smckusick 	if (read(fi, buf, cnt) != cnt) {
2104238Smckusick 		printf("read error %d\n", bno);
2115326Smckusic 		for(i=0; i < cnt; i++)
2124238Smckusick 			buf[i] = 0;
2134238Smckusick 	}
2144238Smckusick }
2154238Smckusick 
2164238Smckusick daddr_t
2174238Smckusick bmap(i)
2184238Smckusick {
2195326Smckusic 	daddr_t ibuf[MAXNINDIR];
2204238Smckusick 
2214238Smckusick 	if(i < NDADDR)
2224253Smckusic 		return(gip->di_db[i]);
2234238Smckusick 	i -= NDADDR;
2245326Smckusic 	if(i > NINDIR(&sblock)) {
2254238Smckusick 		printf("%u - huge directory\n", ino);
2264238Smckusick 		return((daddr_t)0);
2274238Smckusick 	}
2285326Smckusic 	bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
2294238Smckusick 	return(ibuf[i]);
2304238Smckusick }
231