xref: /csrg-svn/old/dcheck/dcheck.c (revision 5946)
1*5946Smckusic static	char *sccsid = "@(#)dcheck.c	1.7 (Berkeley) 02/23/82";
24238Smckusick /*
34238Smckusick  * dcheck - check directory consistency
44238Smckusick  */
54238Smckusick #define	NB	10
65348Smckusic #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
74238Smckusick 
84238Smckusick #include "../h/param.h"
94238Smckusick #include "../h/inode.h"
104238Smckusick #include "../h/fs.h"
11*5946Smckusic #include <ndir.h>
12*5946Smckusic #include <stdio.h>
134238Smckusick 
144238Smckusick union {
154238Smckusick 	struct	fs fs;
165326Smckusic 	char pad[MAXBSIZE];
174238Smckusick } fsun;
184238Smckusick #define	sblock	fsun.fs
194238Smckusick 
20*5946Smckusic struct dirstuff {
21*5946Smckusic 	int loc;
22*5946Smckusic 	struct dinode *ip;
23*5946Smckusic 	char dbuf[MAXBSIZE];
24*5946Smckusic };
25*5946Smckusic 
264238Smckusick struct	dinode	itab[MAXIPG];
274253Smckusic struct	dinode	*gip;
284238Smckusick ino_t	ilist[NB];
294238Smckusick 
304238Smckusick int	fi;
314238Smckusick ino_t	ino;
324238Smckusick ino_t	*ecount;
334238Smckusick int	headpr;
344238Smckusick int	nfiles;
354238Smckusick 
364238Smckusick int	nerror;
374238Smckusick daddr_t	bmap();
384238Smckusick long	atol();
394238Smckusick char	*malloc();
404238Smckusick 
414238Smckusick main(argc, argv)
424238Smckusick char *argv[];
434238Smckusick {
444238Smckusick 	register i;
454238Smckusick 	long n;
464238Smckusick 
474238Smckusick 	while (--argc) {
484238Smckusick 		argv++;
494238Smckusick 		if (**argv=='-')
504238Smckusick 		switch ((*argv)[1]) {
514238Smckusick 
524238Smckusick 		case 'i':
534238Smckusick 			for(i=0; i<NB; i++) {
544238Smckusick 				n = atol(argv[1]);
554238Smckusick 				if(n == 0)
564238Smckusick 					break;
574238Smckusick 				ilist[i] = n;
584238Smckusick 				argv++;
594238Smckusick 				argc--;
604238Smckusick 			}
614238Smckusick 			ilist[i] = 0;
624238Smckusick 			continue;
634238Smckusick 
644238Smckusick 		default:
654238Smckusick 			printf("Bad flag %c\n", (*argv)[1]);
664238Smckusick 			nerror++;
674238Smckusick 		}
684238Smckusick 		check(*argv);
694238Smckusick 	}
704238Smckusick 	return(nerror);
714238Smckusick }
724238Smckusick 
734238Smckusick check(file)
744238Smckusick char *file;
754238Smckusick {
764238Smckusick 	register i, j, c;
774238Smckusick 
784238Smckusick 	fi = open(file, 0);
794238Smckusick 	if(fi < 0) {
804238Smckusick 		printf("cannot open %s\n", file);
814238Smckusick 		nerror++;
824238Smckusick 		return;
834238Smckusick 	}
844238Smckusick 	headpr = 0;
854238Smckusick 	printf("%s:\n", file);
864238Smckusick 	sync();
875348Smckusic 	bread(SBLOCK, (char *)&sblock, SBSIZE);
884238Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
894238Smckusick 		printf("%s: not a file system\n", file);
904238Smckusick 		nerror++;
914238Smckusick 		return;
924238Smckusick 	}
934238Smckusick 	nfiles = sblock.fs_ipg * sblock.fs_ncg;
944238Smckusick 	if (nfiles > 65535) {
954238Smckusick 		printf("%s: preposterous number of files\n", file);
964238Smckusick 		nerror++;
974238Smckusick 		return;
984238Smckusick 	}
994238Smckusick 	ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
1004238Smckusick 	if (ecount == 0) {
1014238Smckusick 		printf("%s: not enough core for %d files\n", file, nfiles);
1024238Smckusick 		exit(04);
1034238Smckusick 	}
1044238Smckusick 	for (i = 0; i<=nfiles; i++)
1054238Smckusick 		ecount[i] = 0;
1064238Smckusick 	ino = 0;
1074238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1085379Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
1094238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1104238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1114238Smckusick 			pass1(&itab[j]);
1124238Smckusick 			ino++;
1134238Smckusick 		}
1144238Smckusick 	}
1154238Smckusick 	ino = 0;
1164238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1175379Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
1184238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1194238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1204238Smckusick 			pass2(&itab[j]);
1214238Smckusick 			ino++;
1224238Smckusick 		}
1234238Smckusick 	}
1244238Smckusick 	free(ecount);
1254238Smckusick }
1264238Smckusick 
1274238Smckusick pass1(ip)
128*5946Smckusic 	register struct dinode *ip;
1294238Smckusick {
130*5946Smckusic 	register struct direct *dp;
131*5946Smckusic 	struct dirstuff dirp;
1324238Smckusick 	int k;
1334238Smckusick 
1344238Smckusick 	if((ip->di_mode&IFMT) != IFDIR)
1354238Smckusick 		return;
136*5946Smckusic 	dirp.loc = 0;
137*5946Smckusic 	dirp.ip = ip;
1384253Smckusic 	gip = ip;
139*5946Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
140*5946Smckusic 		if(dp->d_ino == 0)
141*5946Smckusic 			continue;
142*5946Smckusic 		if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
143*5946Smckusic 			printf("%d bad; %d/%s\n",
144*5946Smckusic 			    dp->d_ino, ino, dp->d_name);
145*5946Smckusic 			nerror++;
146*5946Smckusic 			continue;
147*5946Smckusic 		}
148*5946Smckusic 		for (k = 0; ilist[k] != 0; k++)
149*5946Smckusic 			if (ilist[k] == dp->d_ino) {
150*5946Smckusic 				printf("%d arg; %d/%s\n",
151*5946Smckusic 				     dp->d_ino, ino, dp->d_name);
1524238Smckusick 				nerror++;
1534238Smckusick 			}
154*5946Smckusic 		ecount[dp->d_ino]++;
1554238Smckusick 	}
1564238Smckusick }
1574238Smckusick 
1584238Smckusick pass2(ip)
1594238Smckusick register struct dinode *ip;
1604238Smckusick {
1614238Smckusick 	register i;
1624238Smckusick 
1634238Smckusick 	i = ino;
1644238Smckusick 	if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
1654238Smckusick 		return;
1664238Smckusick 	if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
1674238Smckusick 		return;
1684238Smckusick 	if (headpr==0) {
1694238Smckusick 		printf("     entries  link cnt\n");
1704238Smckusick 		headpr++;
1714238Smckusick 	}
1724238Smckusick 	printf("%u\t%d\t%d\n", ino,
1734238Smckusick 	    ecount[i], ip->di_nlink);
1744238Smckusick }
1754238Smckusick 
176*5946Smckusic /*
177*5946Smckusic  * get next entry in a directory.
178*5946Smckusic  */
179*5946Smckusic struct direct *
180*5946Smckusic readdir(dirp)
181*5946Smckusic 	register struct dirstuff *dirp;
182*5946Smckusic {
183*5946Smckusic 	register struct direct *dp;
184*5946Smckusic 	daddr_t lbn, d;
185*5946Smckusic 
186*5946Smckusic 	for(;;) {
187*5946Smckusic 		if (dirp->loc >= dirp->ip->di_size)
188*5946Smckusic 			return NULL;
189*5946Smckusic 		if ((lbn = dirp->loc / sblock.fs_bsize) == 0) {
190*5946Smckusic 			d = bmap(lbn);
191*5946Smckusic 			if(d == 0)
192*5946Smckusic 				return NULL;
193*5946Smckusic 			bread(fsbtodb(&sblock, d), dirp->dbuf,
194*5946Smckusic 			    dblksize(&sblock, dirp->ip, lbn));
195*5946Smckusic 		}
196*5946Smckusic 		dp = (struct direct *)
197*5946Smckusic 		    (dirp->dbuf + dirp->loc % sblock.fs_bsize);
198*5946Smckusic 		dirp->loc += dp->d_reclen;
199*5946Smckusic 		if (dp->d_ino == 0)
200*5946Smckusic 			continue;
201*5946Smckusic 		return (dp);
202*5946Smckusic 	}
203*5946Smckusic }
204*5946Smckusic 
2054238Smckusick bread(bno, buf, cnt)
2064238Smckusick daddr_t bno;
2074238Smckusick char *buf;
2084238Smckusick {
2094238Smckusick 	register i;
2104238Smckusick 
2115326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
2124238Smckusick 	if (read(fi, buf, cnt) != cnt) {
2134238Smckusick 		printf("read error %d\n", bno);
2145326Smckusic 		for(i=0; i < cnt; i++)
2154238Smckusick 			buf[i] = 0;
2164238Smckusick 	}
2174238Smckusick }
2184238Smckusick 
2194238Smckusick daddr_t
2204238Smckusick bmap(i)
2214238Smckusick {
2225326Smckusic 	daddr_t ibuf[MAXNINDIR];
2234238Smckusick 
2244238Smckusick 	if(i < NDADDR)
2254253Smckusic 		return(gip->di_db[i]);
2264238Smckusick 	i -= NDADDR;
2275326Smckusic 	if(i > NINDIR(&sblock)) {
2284238Smckusick 		printf("%u - huge directory\n", ino);
2294238Smckusick 		return((daddr_t)0);
2304238Smckusick 	}
2315326Smckusic 	bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
2324238Smckusick 	return(ibuf[i]);
2334238Smckusick }
234