xref: /csrg-svn/old/dcheck/dcheck.c (revision 4238)
1*4238Smckusick static	char *sccsid = "@(#)dcheck.c	1.1 (Berkeley) 08/26/81";
2*4238Smckusick /*
3*4238Smckusick  * dcheck - check directory consistency
4*4238Smckusick  */
5*4238Smckusick #define	NB	10
6*4238Smckusick #define	NDIR	(BSIZE/sizeof(struct direct))
7*4238Smckusick 
8*4238Smckusick #include <stdio.h>
9*4238Smckusick #include "../h/param.h"
10*4238Smckusick #include "../h/inode.h"
11*4238Smckusick #include "../h/ino.h"
12*4238Smckusick #include "../h/dir.h"
13*4238Smckusick #include "../h/fs.h"
14*4238Smckusick 
15*4238Smckusick union {
16*4238Smckusick 	struct	fs fs;
17*4238Smckusick 	char pad[BSIZE];
18*4238Smckusick } fsun;
19*4238Smckusick #define	sblock	fsun.fs
20*4238Smckusick 
21*4238Smckusick struct	dinode	itab[MAXIPG];
22*4238Smckusick daddr_t	iaddr[NDADDR+NIADDR];
23*4238Smckusick ino_t	ilist[NB];
24*4238Smckusick 
25*4238Smckusick int	fi;
26*4238Smckusick ino_t	ino;
27*4238Smckusick ino_t	*ecount;
28*4238Smckusick int	headpr;
29*4238Smckusick int	nfiles;
30*4238Smckusick 
31*4238Smckusick int	nerror;
32*4238Smckusick daddr_t	bmap();
33*4238Smckusick long	atol();
34*4238Smckusick char	*malloc();
35*4238Smckusick 
36*4238Smckusick main(argc, argv)
37*4238Smckusick char *argv[];
38*4238Smckusick {
39*4238Smckusick 	register i;
40*4238Smckusick 	long n;
41*4238Smckusick 
42*4238Smckusick 	while (--argc) {
43*4238Smckusick 		argv++;
44*4238Smckusick 		if (**argv=='-')
45*4238Smckusick 		switch ((*argv)[1]) {
46*4238Smckusick 
47*4238Smckusick 		case 'i':
48*4238Smckusick 			for(i=0; i<NB; i++) {
49*4238Smckusick 				n = atol(argv[1]);
50*4238Smckusick 				if(n == 0)
51*4238Smckusick 					break;
52*4238Smckusick 				ilist[i] = n;
53*4238Smckusick 				argv++;
54*4238Smckusick 				argc--;
55*4238Smckusick 			}
56*4238Smckusick 			ilist[i] = 0;
57*4238Smckusick 			continue;
58*4238Smckusick 
59*4238Smckusick 		default:
60*4238Smckusick 			printf("Bad flag %c\n", (*argv)[1]);
61*4238Smckusick 			nerror++;
62*4238Smckusick 		}
63*4238Smckusick 		check(*argv);
64*4238Smckusick 	}
65*4238Smckusick 	return(nerror);
66*4238Smckusick }
67*4238Smckusick 
68*4238Smckusick check(file)
69*4238Smckusick char *file;
70*4238Smckusick {
71*4238Smckusick 	register i, j, c;
72*4238Smckusick 
73*4238Smckusick 	fi = open(file, 0);
74*4238Smckusick 	if(fi < 0) {
75*4238Smckusick 		printf("cannot open %s\n", file);
76*4238Smckusick 		nerror++;
77*4238Smckusick 		return;
78*4238Smckusick 	}
79*4238Smckusick 	headpr = 0;
80*4238Smckusick 	printf("%s:\n", file);
81*4238Smckusick 	sync();
82*4238Smckusick 	bread(SBLOCK, (char *)&sblock, BSIZE);
83*4238Smckusick 	if (sblock.fs_magic != FS_MAGIC) {
84*4238Smckusick 		printf("%s: not a file system\n", file);
85*4238Smckusick 		nerror++;
86*4238Smckusick 		return;
87*4238Smckusick 	}
88*4238Smckusick 	nfiles = sblock.fs_ipg * sblock.fs_ncg;
89*4238Smckusick 	if (nfiles > 65535) {
90*4238Smckusick 		printf("%s: preposterous number of files\n", file);
91*4238Smckusick 		nerror++;
92*4238Smckusick 		return;
93*4238Smckusick 	}
94*4238Smckusick 	ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount));
95*4238Smckusick 	if (ecount == 0) {
96*4238Smckusick 		printf("%s: not enough core for %d files\n", file, nfiles);
97*4238Smckusick 		exit(04);
98*4238Smckusick 	}
99*4238Smckusick 	for (i = 0; i<=nfiles; i++)
100*4238Smckusick 		ecount[i] = 0;
101*4238Smckusick 	ino = 0;
102*4238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
103*4238Smckusick 		bread(cgimin(c, &sblock), (char *)itab,
104*4238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
105*4238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
106*4238Smckusick 			pass1(&itab[j]);
107*4238Smckusick 			ino++;
108*4238Smckusick 		}
109*4238Smckusick 	}
110*4238Smckusick 	ino = 0;
111*4238Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
112*4238Smckusick 		bread(cgimin(c, &sblock), (char *)itab,
113*4238Smckusick 		    sblock.fs_ipg * sizeof (struct dinode));
114*4238Smckusick 		for (j = 0; j < sblock.fs_ipg; j++) {
115*4238Smckusick 			pass2(&itab[j]);
116*4238Smckusick 			ino++;
117*4238Smckusick 		}
118*4238Smckusick 	}
119*4238Smckusick 	free(ecount);
120*4238Smckusick }
121*4238Smckusick 
122*4238Smckusick pass1(ip)
123*4238Smckusick register struct dinode *ip;
124*4238Smckusick {
125*4238Smckusick 	struct direct dbuf[NDIR];
126*4238Smckusick 	long doff;
127*4238Smckusick 	struct direct *dp;
128*4238Smckusick 	register i, j;
129*4238Smckusick 	int k;
130*4238Smckusick 	daddr_t d;
131*4238Smckusick 	ino_t kno;
132*4238Smckusick 
133*4238Smckusick 	if((ip->di_mode&IFMT) != IFDIR)
134*4238Smckusick 		return;
135*4238Smckusick 	l3tol(iaddr, ip->di_addr, NDADDR+NIADDR);
136*4238Smckusick 	doff = 0;
137*4238Smckusick 	for(i=0;; i++) {
138*4238Smckusick 		if(doff >= ip->di_size)
139*4238Smckusick 			break;
140*4238Smckusick 		d = bmap(i);
141*4238Smckusick 		if(d == 0)
142*4238Smckusick 			break;
143*4238Smckusick 		bread(d, (char *)dbuf, BSIZE);
144*4238Smckusick 		for(j=0; j<NDIR; j++) {
145*4238Smckusick 			if(doff >= ip->di_size)
146*4238Smckusick 				break;
147*4238Smckusick 			doff += sizeof(struct direct);
148*4238Smckusick 			dp = &dbuf[j];
149*4238Smckusick 			kno = dp->d_ino;
150*4238Smckusick 			if(kno == 0)
151*4238Smckusick 				continue;
152*4238Smckusick 			if(kno > nfiles || kno < ROOTINO) {
153*4238Smckusick 				printf("%d bad; %d/%.*s\n",
154*4238Smckusick 				    kno, ino, DIRSIZ, dp->d_name);
155*4238Smckusick 				nerror++;
156*4238Smckusick 				continue;
157*4238Smckusick 			}
158*4238Smckusick 			for (k=0; ilist[k] != 0; k++)
159*4238Smckusick 				if (ilist[k]==kno) {
160*4238Smckusick 					printf("%d arg; %d/%.*s\n",
161*4238Smckusick 					    kno, ino, DIRSIZ, dp->d_name);
162*4238Smckusick 					nerror++;
163*4238Smckusick 				}
164*4238Smckusick 			ecount[kno]++;
165*4238Smckusick 		}
166*4238Smckusick 	}
167*4238Smckusick }
168*4238Smckusick 
169*4238Smckusick pass2(ip)
170*4238Smckusick register struct dinode *ip;
171*4238Smckusick {
172*4238Smckusick 	register i;
173*4238Smckusick 
174*4238Smckusick 	i = ino;
175*4238Smckusick 	if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
176*4238Smckusick 		return;
177*4238Smckusick 	if (ip->di_nlink==ecount[i] && ip->di_nlink!=0)
178*4238Smckusick 		return;
179*4238Smckusick 	if (headpr==0) {
180*4238Smckusick 		printf("     entries  link cnt\n");
181*4238Smckusick 		headpr++;
182*4238Smckusick 	}
183*4238Smckusick 	printf("%u\t%d\t%d\n", ino,
184*4238Smckusick 	    ecount[i], ip->di_nlink);
185*4238Smckusick }
186*4238Smckusick 
187*4238Smckusick bread(bno, buf, cnt)
188*4238Smckusick daddr_t bno;
189*4238Smckusick char *buf;
190*4238Smckusick {
191*4238Smckusick 	register i;
192*4238Smckusick 
193*4238Smckusick 	lseek(fi, bno*FSIZE, 0);
194*4238Smckusick 	if (read(fi, buf, cnt) != cnt) {
195*4238Smckusick 		printf("read error %d\n", bno);
196*4238Smckusick 		for(i=0; i<BSIZE; i++)
197*4238Smckusick 			buf[i] = 0;
198*4238Smckusick 	}
199*4238Smckusick }
200*4238Smckusick 
201*4238Smckusick daddr_t
202*4238Smckusick bmap(i)
203*4238Smckusick {
204*4238Smckusick 	daddr_t ibuf[NINDIR];
205*4238Smckusick 
206*4238Smckusick 	if(i < NDADDR)
207*4238Smckusick 		return(iaddr[i]);
208*4238Smckusick 	i -= NDADDR;
209*4238Smckusick 	if(i > NINDIR) {
210*4238Smckusick 		printf("%u - huge directory\n", ino);
211*4238Smckusick 		return((daddr_t)0);
212*4238Smckusick 	}
213*4238Smckusick 	bread(iaddr[NDADDR], (char *)ibuf, sizeof(ibuf));
214*4238Smckusick 	return(ibuf[i]);
215*4238Smckusick }
216