xref: /csrg-svn/old/dcheck/dcheck.c (revision 38504)
122489Sdist /*
222489Sdist  * Copyright (c) 1980 Regents of the University of California.
322489Sdist  * All rights reserved.  The Berkeley software License Agreement
422489Sdist  * specifies the terms and conditions for redistribution.
522489Sdist  */
622489Sdist 
713550Ssam #ifndef lint
822489Sdist char copyright[] =
922489Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
1022489Sdist  All rights reserved.\n";
1122489Sdist #endif not lint
1222489Sdist 
1322489Sdist #ifndef lint
14*38504Sbostic static char sccsid[] = "@(#)dcheck.c	5.4 (Berkeley) 07/30/89";
1522489Sdist #endif not lint
1622489Sdist 
174238Smckusick /*
184238Smckusick  * dcheck - check directory consistency
194238Smckusick  */
204238Smckusick #define	NB	10
215348Smckusic #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
224238Smckusick 
236493Smckusick #include <sys/param.h>
24*38504Sbostic #include <sys/time.h>
25*38504Sbostic #include <sys/vnode.h>
26*38504Sbostic #include <ufs/inode.h>
27*38504Sbostic #include <ufs/fs.h>
2813550Ssam #include <sys/dir.h>
295946Smckusic #include <stdio.h>
304238Smckusick 
314238Smckusick union {
324238Smckusick 	struct	fs fs;
3334151Smckusick 	char pad[SBSIZE];
344238Smckusick } fsun;
354238Smckusick #define	sblock	fsun.fs
364238Smckusick 
375946Smckusic struct dirstuff {
385946Smckusic 	int loc;
395946Smckusic 	struct dinode *ip;
405946Smckusic 	char dbuf[MAXBSIZE];
415946Smckusic };
425946Smckusic 
4334151Smckusick struct	dinode	itab[MAXBSIZE / sizeof(struct dinode)];
444253Smckusic struct	dinode	*gip;
454238Smckusick ino_t	ilist[NB];
464238Smckusick 
474238Smckusick int	fi;
484238Smckusick ino_t	ino;
494238Smckusick ino_t	*ecount;
504238Smckusick int	headpr;
514238Smckusick int	nfiles;
5230558Smckusick long	dev_bsize = 1;
534238Smckusick 
544238Smckusick int	nerror;
554238Smckusick daddr_t	bmap();
564238Smckusick long	atol();
574238Smckusick char	*malloc();
584238Smckusick 
main(argc,argv)594238Smckusick main(argc, argv)
604238Smckusick char *argv[];
614238Smckusick {
624238Smckusick 	register i;
634238Smckusick 	long n;
644238Smckusick 
654238Smckusick 	while (--argc) {
664238Smckusick 		argv++;
674238Smckusick 		if (**argv=='-')
684238Smckusick 		switch ((*argv)[1]) {
694238Smckusick 
704238Smckusick 		case 'i':
714238Smckusick 			for(i=0; i<NB; i++) {
724238Smckusick 				n = atol(argv[1]);
734238Smckusick 				if(n == 0)
744238Smckusick 					break;
754238Smckusick 				ilist[i] = n;
764238Smckusick 				argv++;
774238Smckusick 				argc--;
784238Smckusick 			}
794238Smckusick 			ilist[i] = 0;
804238Smckusick 			continue;
814238Smckusick 
824238Smckusick 		default:
834238Smckusick 			printf("Bad flag %c\n", (*argv)[1]);
844238Smckusick 			nerror++;
854238Smckusick 		}
864238Smckusick 		check(*argv);
874238Smckusick 	}
884238Smckusick 	return(nerror);
894238Smckusick }
904238Smckusick 
check(file)914238Smckusick check(file)
924238Smckusick char *file;
934238Smckusick {
944238Smckusick 	register i, j, c;
954238Smckusick 
964238Smckusick 	fi = open(file, 0);
974238Smckusick 	if(fi < 0) {
984238Smckusick 		printf("cannot open %s\n", file);
994238Smckusick 		nerror++;
1004238Smckusick 		return;
1014238Smckusick 	}
1024238Smckusick 	headpr = 0;
1034238Smckusick 	printf("%s:\n", file);
1044238Smckusick 	sync();
10530558Smckusick 	bread(SBOFF, (char *)&sblock, SBSIZE);
1064238Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
1074238Smckusick 		printf("%s: not a file system\n", file);
1084238Smckusick 		nerror++;
1094238Smckusick 		return;
1104238Smckusick 	}
11130558Smckusick 	dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
1124238Smckusick 	nfiles = sblock.fs_ipg * sblock.fs_ncg;
1134238Smckusick 	ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
1144238Smckusick 	if (ecount == 0) {
1154238Smckusick 		printf("%s: not enough core for %d files\n", file, nfiles);
1164238Smckusick 		exit(04);
1174238Smckusick 	}
1184238Smckusick 	for (i = 0; i<=nfiles; i++)
1194238Smckusick 		ecount[i] = 0;
1204238Smckusick 	ino = 0;
1214238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
12234151Smckusick 		for (i = 0;
12334151Smckusick 		     i < sblock.fs_ipg / INOPF(&sblock);
12434151Smckusick 		     i += sblock.fs_frag) {
12534151Smckusick 			bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
12634151Smckusick 			    (char *)itab, sblock.fs_bsize);
12734151Smckusick 			for (j = 0; j < INOPB(&sblock); j++) {
12834151Smckusick 				pass1(&itab[j]);
12934151Smckusick 				ino++;
13034151Smckusick 			}
1314238Smckusick 		}
1324238Smckusick 	}
1334238Smckusick 	ino = 0;
1344238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
13534151Smckusick 		for (i = 0;
13634151Smckusick 		     i < sblock.fs_ipg / INOPF(&sblock);
13734151Smckusick 		     i += sblock.fs_frag) {
13834151Smckusick 			bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
13934151Smckusick 			    (char *)itab, sblock.fs_bsize);
14034151Smckusick 			for (j = 0; j < INOPB(&sblock); j++) {
14134151Smckusick 				pass2(&itab[j]);
14234151Smckusick 				ino++;
14334151Smckusick 			}
1444238Smckusick 		}
1454238Smckusick 	}
1464238Smckusick 	free(ecount);
1474238Smckusick }
1484238Smckusick 
pass1(ip)1494238Smckusick pass1(ip)
1505946Smckusic 	register struct dinode *ip;
1514238Smckusick {
1525946Smckusic 	register struct direct *dp;
1535946Smckusic 	struct dirstuff dirp;
1544238Smckusick 	int k;
1554238Smckusick 
1564238Smckusick 	if((ip->di_mode&IFMT) != IFDIR)
1574238Smckusick 		return;
1585946Smckusic 	dirp.loc = 0;
1595946Smckusic 	dirp.ip = ip;
1604253Smckusic 	gip = ip;
1615946Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
1625946Smckusic 		if(dp->d_ino == 0)
1635946Smckusic 			continue;
1645946Smckusic 		if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
1655946Smckusic 			printf("%d bad; %d/%s\n",
1665946Smckusic 			    dp->d_ino, ino, dp->d_name);
1675946Smckusic 			nerror++;
1685946Smckusic 			continue;
1695946Smckusic 		}
1705946Smckusic 		for (k = 0; ilist[k] != 0; k++)
1715946Smckusic 			if (ilist[k] == dp->d_ino) {
1725946Smckusic 				printf("%d arg; %d/%s\n",
1735946Smckusic 				     dp->d_ino, ino, dp->d_name);
1744238Smckusick 				nerror++;
1754238Smckusick 			}
1765946Smckusic 		ecount[dp->d_ino]++;
1774238Smckusick 	}
1784238Smckusick }
1794238Smckusick 
pass2(ip)1804238Smckusick pass2(ip)
1814238Smckusick register struct dinode *ip;
1824238Smckusick {
1834238Smckusick 	register i;
1844238Smckusick 
1854238Smckusick 	i = ino;
1864238Smckusick 	if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
1874238Smckusick 		return;
1884238Smckusick 	if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
1894238Smckusick 		return;
1904238Smckusick 	if (headpr==0) {
1914238Smckusick 		printf("     entries  link cnt\n");
1924238Smckusick 		headpr++;
1934238Smckusick 	}
1944238Smckusick 	printf("%u\t%d\t%d\n", ino,
1954238Smckusick 	    ecount[i], ip->di_nlink);
1964238Smckusick }
1974238Smckusick 
1985946Smckusic /*
1995946Smckusic  * get next entry in a directory.
2005946Smckusic  */
2015946Smckusic struct direct *
readdir(dirp)2025946Smckusic readdir(dirp)
2035946Smckusic 	register struct dirstuff *dirp;
2045946Smckusic {
2055946Smckusic 	register struct direct *dp;
2065946Smckusic 	daddr_t lbn, d;
2075946Smckusic 
2085946Smckusic 	for(;;) {
2095946Smckusic 		if (dirp->loc >= dirp->ip->di_size)
2105946Smckusic 			return NULL;
2115957Smckusic 		if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
2125946Smckusic 			d = bmap(lbn);
2135946Smckusic 			if(d == 0)
2145946Smckusic 				return NULL;
2155946Smckusic 			bread(fsbtodb(&sblock, d), dirp->dbuf,
2165946Smckusic 			    dblksize(&sblock, dirp->ip, lbn));
2175946Smckusic 		}
2185946Smckusic 		dp = (struct direct *)
2195957Smckusic 		    (dirp->dbuf + blkoff(&sblock, dirp->loc));
2205946Smckusic 		dirp->loc += dp->d_reclen;
2215946Smckusic 		if (dp->d_ino == 0)
2225946Smckusic 			continue;
2235946Smckusic 		return (dp);
2245946Smckusic 	}
2255946Smckusic }
2265946Smckusic 
bread(bno,buf,cnt)2274238Smckusick bread(bno, buf, cnt)
2284238Smckusick daddr_t bno;
2294238Smckusick char *buf;
2304238Smckusick {
2314238Smckusick 	register i;
2324238Smckusick 
23330558Smckusick 	lseek(fi, bno * dev_bsize, 0);
2344238Smckusick 	if (read(fi, buf, cnt) != cnt) {
2354238Smckusick 		printf("read error %d\n", bno);
2365326Smckusic 		for(i=0; i < cnt; i++)
2374238Smckusick 			buf[i] = 0;
2384238Smckusick 	}
2394238Smckusick }
2404238Smckusick 
2414238Smckusick daddr_t
bmap(i)2424238Smckusick bmap(i)
2434238Smckusick {
2445326Smckusic 	daddr_t ibuf[MAXNINDIR];
2454238Smckusick 
2464238Smckusick 	if(i < NDADDR)
2474253Smckusic 		return(gip->di_db[i]);
2484238Smckusick 	i -= NDADDR;
2495326Smckusic 	if(i > NINDIR(&sblock)) {
2504238Smckusick 		printf("%u - huge directory\n", ino);
2514238Smckusick 		return((daddr_t)0);
2524238Smckusick 	}
2535326Smckusic 	bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
2544238Smckusick 	return(ibuf[i]);
2554238Smckusick }
256