Commit | Line | Data |
---|---|---|
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 | ||
17 | struct filsys sblock; | |
18 | struct dinode itab[INOPB*NI]; | |
19 | daddr_t iaddr[NADDR]; | |
20 | ino_t ilist[NB]; | |
21 | ||
22 | int fi; | |
23 | ino_t ino; | |
24 | char *ecount; | |
25 | int headpr; | |
26 | unsigned nfiles; | |
27 | ||
28 | int nerror; | |
29 | daddr_t bmap(); | |
30 | long atol(); | |
31 | char *malloc(); | |
32 | ||
33 | main(argc, argv) | |
34 | char *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 | ||
65 | check(file) | |
66 | char *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 | ||
120 | pass1(ip) | |
121 | register 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 | ||
167 | pass2(ip) | |
168 | register 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 | ||
185 | bread(bno, buf, cnt) | |
186 | daddr_t bno; | |
187 | char *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 | ||
200 | daddr_t | |
201 | bmap(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 | } |