xref: /csrg-svn/old/dcheck/dcheck.c (revision 22489)
1*22489Sdist /*
2*22489Sdist  * Copyright (c) 1980 Regents of the University of California.
3*22489Sdist  * All rights reserved.  The Berkeley software License Agreement
4*22489Sdist  * specifies the terms and conditions for redistribution.
5*22489Sdist  */
6*22489Sdist 
713550Ssam #ifndef lint
8*22489Sdist char copyright[] =
9*22489Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10*22489Sdist  All rights reserved.\n";
11*22489Sdist #endif not lint
12*22489Sdist 
13*22489Sdist #ifndef lint
14*22489Sdist static char sccsid[] = "@(#)dcheck.c	5.1 (Berkeley) 06/06/85";
15*22489Sdist #endif not lint
16*22489Sdist 
174238Smckusick /*
184238Smckusick  * dcheck - check directory consistency
194238Smckusick  */
204238Smckusick #define	NB	10
215348Smckusic #define	MAXNINDIR	(MAXBSIZE / sizeof (daddr_t))
224238Smckusick 
236493Smckusick #include <sys/param.h>
246493Smckusick #include <sys/inode.h>
256493Smckusick #include <sys/fs.h>
2613550Ssam #include <sys/dir.h>
275946Smckusic #include <stdio.h>
284238Smckusick 
294238Smckusick union {
304238Smckusick 	struct	fs fs;
315326Smckusic 	char pad[MAXBSIZE];
324238Smckusick } fsun;
334238Smckusick #define	sblock	fsun.fs
344238Smckusick 
355946Smckusic struct dirstuff {
365946Smckusic 	int loc;
375946Smckusic 	struct dinode *ip;
385946Smckusic 	char dbuf[MAXBSIZE];
395946Smckusic };
405946Smckusic 
414238Smckusick struct	dinode	itab[MAXIPG];
424253Smckusic struct	dinode	*gip;
434238Smckusick ino_t	ilist[NB];
444238Smckusick 
454238Smckusick int	fi;
464238Smckusick ino_t	ino;
474238Smckusick ino_t	*ecount;
484238Smckusick int	headpr;
494238Smckusick int	nfiles;
504238Smckusick 
514238Smckusick int	nerror;
524238Smckusick daddr_t	bmap();
534238Smckusick long	atol();
544238Smckusick char	*malloc();
554238Smckusick 
564238Smckusick main(argc, argv)
574238Smckusick char *argv[];
584238Smckusick {
594238Smckusick 	register i;
604238Smckusick 	long n;
614238Smckusick 
624238Smckusick 	while (--argc) {
634238Smckusick 		argv++;
644238Smckusick 		if (**argv=='-')
654238Smckusick 		switch ((*argv)[1]) {
664238Smckusick 
674238Smckusick 		case 'i':
684238Smckusick 			for(i=0; i<NB; i++) {
694238Smckusick 				n = atol(argv[1]);
704238Smckusick 				if(n == 0)
714238Smckusick 					break;
724238Smckusick 				ilist[i] = n;
734238Smckusick 				argv++;
744238Smckusick 				argc--;
754238Smckusick 			}
764238Smckusick 			ilist[i] = 0;
774238Smckusick 			continue;
784238Smckusick 
794238Smckusick 		default:
804238Smckusick 			printf("Bad flag %c\n", (*argv)[1]);
814238Smckusick 			nerror++;
824238Smckusick 		}
834238Smckusick 		check(*argv);
844238Smckusick 	}
854238Smckusick 	return(nerror);
864238Smckusick }
874238Smckusick 
884238Smckusick check(file)
894238Smckusick char *file;
904238Smckusick {
914238Smckusick 	register i, j, c;
924238Smckusick 
934238Smckusick 	fi = open(file, 0);
944238Smckusick 	if(fi < 0) {
954238Smckusick 		printf("cannot open %s\n", file);
964238Smckusick 		nerror++;
974238Smckusick 		return;
984238Smckusick 	}
994238Smckusick 	headpr = 0;
1004238Smckusick 	printf("%s:\n", file);
1014238Smckusick 	sync();
1025348Smckusic 	bread(SBLOCK, (char *)&sblock, SBSIZE);
1034238Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
1044238Smckusick 		printf("%s: not a file system\n", file);
1054238Smckusick 		nerror++;
1064238Smckusick 		return;
1074238Smckusick 	}
1084238Smckusick 	nfiles = sblock.fs_ipg * sblock.fs_ncg;
1094238Smckusick 	ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
1104238Smckusick 	if (ecount == 0) {
1114238Smckusick 		printf("%s: not enough core for %d files\n", file, nfiles);
1124238Smckusick 		exit(04);
1134238Smckusick 	}
1144238Smckusick 	for (i = 0; i<=nfiles; i++)
1154238Smckusick 		ecount[i] = 0;
1164238Smckusick 	ino = 0;
1174238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1185379Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
1194238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1204238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1214238Smckusick 			pass1(&itab[j]);
1224238Smckusick 			ino++;
1234238Smckusick 		}
1244238Smckusick 	}
1254238Smckusick 	ino = 0;
1264238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
1275379Smckusic 		bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
1284238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
1294238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
1304238Smckusick 			pass2(&itab[j]);
1314238Smckusick 			ino++;
1324238Smckusick 		}
1334238Smckusick 	}
1344238Smckusick 	free(ecount);
1354238Smckusick }
1364238Smckusick 
1374238Smckusick pass1(ip)
1385946Smckusic 	register struct dinode *ip;
1394238Smckusick {
1405946Smckusic 	register struct direct *dp;
1415946Smckusic 	struct dirstuff dirp;
1424238Smckusick 	int k;
1434238Smckusick 
1444238Smckusick 	if((ip->di_mode&IFMT) != IFDIR)
1454238Smckusick 		return;
1465946Smckusic 	dirp.loc = 0;
1475946Smckusic 	dirp.ip = ip;
1484253Smckusic 	gip = ip;
1495946Smckusic 	for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) {
1505946Smckusic 		if(dp->d_ino == 0)
1515946Smckusic 			continue;
1525946Smckusic 		if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) {
1535946Smckusic 			printf("%d bad; %d/%s\n",
1545946Smckusic 			    dp->d_ino, ino, dp->d_name);
1555946Smckusic 			nerror++;
1565946Smckusic 			continue;
1575946Smckusic 		}
1585946Smckusic 		for (k = 0; ilist[k] != 0; k++)
1595946Smckusic 			if (ilist[k] == dp->d_ino) {
1605946Smckusic 				printf("%d arg; %d/%s\n",
1615946Smckusic 				     dp->d_ino, ino, dp->d_name);
1624238Smckusick 				nerror++;
1634238Smckusick 			}
1645946Smckusic 		ecount[dp->d_ino]++;
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 
1865946Smckusic /*
1875946Smckusic  * get next entry in a directory.
1885946Smckusic  */
1895946Smckusic struct direct *
1905946Smckusic readdir(dirp)
1915946Smckusic 	register struct dirstuff *dirp;
1925946Smckusic {
1935946Smckusic 	register struct direct *dp;
1945946Smckusic 	daddr_t lbn, d;
1955946Smckusic 
1965946Smckusic 	for(;;) {
1975946Smckusic 		if (dirp->loc >= dirp->ip->di_size)
1985946Smckusic 			return NULL;
1995957Smckusic 		if ((lbn = lblkno(&sblock, dirp->loc)) == 0) {
2005946Smckusic 			d = bmap(lbn);
2015946Smckusic 			if(d == 0)
2025946Smckusic 				return NULL;
2035946Smckusic 			bread(fsbtodb(&sblock, d), dirp->dbuf,
2045946Smckusic 			    dblksize(&sblock, dirp->ip, lbn));
2055946Smckusic 		}
2065946Smckusic 		dp = (struct direct *)
2075957Smckusic 		    (dirp->dbuf + blkoff(&sblock, dirp->loc));
2085946Smckusic 		dirp->loc += dp->d_reclen;
2095946Smckusic 		if (dp->d_ino == 0)
2105946Smckusic 			continue;
2115946Smckusic 		return (dp);
2125946Smckusic 	}
2135946Smckusic }
2145946Smckusic 
2154238Smckusick bread(bno, buf, cnt)
2164238Smckusick daddr_t bno;
2174238Smckusick char *buf;
2184238Smckusick {
2194238Smckusick 	register i;
2204238Smckusick 
2215326Smckusic 	lseek(fi, bno * DEV_BSIZE, 0);
2224238Smckusick 	if (read(fi, buf, cnt) != cnt) {
2234238Smckusick 		printf("read error %d\n", bno);
2245326Smckusic 		for(i=0; i < cnt; i++)
2254238Smckusick 			buf[i] = 0;
2264238Smckusick 	}
2274238Smckusick }
2284238Smckusick 
2294238Smckusick daddr_t
2304238Smckusick bmap(i)
2314238Smckusick {
2325326Smckusic 	daddr_t ibuf[MAXNINDIR];
2334238Smckusick 
2344238Smckusick 	if(i < NDADDR)
2354253Smckusic 		return(gip->di_db[i]);
2364238Smckusick 	i -= NDADDR;
2375326Smckusic 	if(i > NINDIR(&sblock)) {
2384238Smckusick 		printf("%u - huge directory\n", ino);
2394238Smckusick 		return((daddr_t)0);
2404238Smckusick 	}
2415326Smckusic 	bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf));
2424238Smckusick 	return(ibuf[i]);
2434238Smckusick }
244