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