Commit | Line | Data |
---|---|---|
da158ee3 DF |
1 | /* |
2 | * Copyright (c) 1980 Regents of the University of California. | |
3 | * All rights reserved. The Berkeley software License Agreement | |
4 | * specifies the terms and conditions for redistribution. | |
5 | */ | |
6 | ||
a7b24fe9 | 7 | #ifndef lint |
da158ee3 DF |
8 | char copyright[] = |
9 | "@(#) Copyright (c) 1980 Regents of the University of California.\n\ | |
10 | All rights reserved.\n"; | |
11 | #endif not lint | |
12 | ||
13 | #ifndef lint | |
806d9347 | 14 | static char sccsid[] = "@(#)dcheck.c 5.3 (Berkeley) %G%"; |
da158ee3 DF |
15 | #endif not lint |
16 | ||
e19a5dd5 KM |
17 | /* |
18 | * dcheck - check directory consistency | |
19 | */ | |
20 | #define NB 10 | |
c312eebd | 21 | #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) |
e19a5dd5 | 22 | |
45eb394d KM |
23 | #include <sys/param.h> |
24 | #include <sys/inode.h> | |
25 | #include <sys/fs.h> | |
a7b24fe9 | 26 | #include <sys/dir.h> |
5086d197 | 27 | #include <stdio.h> |
e19a5dd5 KM |
28 | |
29 | union { | |
30 | struct fs fs; | |
806d9347 | 31 | char pad[SBSIZE]; |
e19a5dd5 KM |
32 | } fsun; |
33 | #define sblock fsun.fs | |
34 | ||
5086d197 KM |
35 | struct dirstuff { |
36 | int loc; | |
37 | struct dinode *ip; | |
38 | char dbuf[MAXBSIZE]; | |
39 | }; | |
40 | ||
806d9347 | 41 | struct dinode itab[MAXBSIZE / sizeof(struct dinode)]; |
56d45dcd | 42 | struct dinode *gip; |
e19a5dd5 KM |
43 | ino_t ilist[NB]; |
44 | ||
45 | int fi; | |
46 | ino_t ino; | |
47 | ino_t *ecount; | |
48 | int headpr; | |
49 | int nfiles; | |
a66ab591 | 50 | long dev_bsize = 1; |
e19a5dd5 KM |
51 | |
52 | int nerror; | |
53 | daddr_t bmap(); | |
54 | long atol(); | |
55 | char *malloc(); | |
56 | ||
57 | main(argc, argv) | |
58 | char *argv[]; | |
59 | { | |
60 | register i; | |
61 | long n; | |
62 | ||
63 | while (--argc) { | |
64 | argv++; | |
65 | if (**argv=='-') | |
66 | switch ((*argv)[1]) { | |
67 | ||
68 | case 'i': | |
69 | for(i=0; i<NB; i++) { | |
70 | n = atol(argv[1]); | |
71 | if(n == 0) | |
72 | break; | |
73 | ilist[i] = n; | |
74 | argv++; | |
75 | argc--; | |
76 | } | |
77 | ilist[i] = 0; | |
78 | continue; | |
79 | ||
80 | default: | |
81 | printf("Bad flag %c\n", (*argv)[1]); | |
82 | nerror++; | |
83 | } | |
84 | check(*argv); | |
85 | } | |
86 | return(nerror); | |
87 | } | |
88 | ||
89 | check(file) | |
90 | char *file; | |
91 | { | |
92 | register i, j, c; | |
93 | ||
94 | fi = open(file, 0); | |
95 | if(fi < 0) { | |
96 | printf("cannot open %s\n", file); | |
97 | nerror++; | |
98 | return; | |
99 | } | |
100 | headpr = 0; | |
101 | printf("%s:\n", file); | |
102 | sync(); | |
a66ab591 | 103 | bread(SBOFF, (char *)&sblock, SBSIZE); |
e19a5dd5 KM |
104 | if (sblock.fs_magic != FS_MAGIC) { |
105 | printf("%s: not a file system\n", file); | |
106 | nerror++; | |
107 | return; | |
108 | } | |
a66ab591 | 109 | dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); |
e19a5dd5 | 110 | nfiles = sblock.fs_ipg * sblock.fs_ncg; |
e19a5dd5 KM |
111 | ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); |
112 | if (ecount == 0) { | |
113 | printf("%s: not enough core for %d files\n", file, nfiles); | |
114 | exit(04); | |
115 | } | |
116 | for (i = 0; i<=nfiles; i++) | |
117 | ecount[i] = 0; | |
118 | ino = 0; | |
119 | for (c = 0; c < sblock.fs_ncg; c++) { | |
806d9347 KM |
120 | for (i = 0; |
121 | i < sblock.fs_ipg / INOPF(&sblock); | |
122 | i += sblock.fs_frag) { | |
123 | bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), | |
124 | (char *)itab, sblock.fs_bsize); | |
125 | for (j = 0; j < INOPB(&sblock); j++) { | |
126 | pass1(&itab[j]); | |
127 | ino++; | |
128 | } | |
e19a5dd5 KM |
129 | } |
130 | } | |
131 | ino = 0; | |
132 | for (c = 0; c < sblock.fs_ncg; c++) { | |
806d9347 KM |
133 | for (i = 0; |
134 | i < sblock.fs_ipg / INOPF(&sblock); | |
135 | i += sblock.fs_frag) { | |
136 | bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), | |
137 | (char *)itab, sblock.fs_bsize); | |
138 | for (j = 0; j < INOPB(&sblock); j++) { | |
139 | pass2(&itab[j]); | |
140 | ino++; | |
141 | } | |
e19a5dd5 KM |
142 | } |
143 | } | |
144 | free(ecount); | |
145 | } | |
146 | ||
147 | pass1(ip) | |
5086d197 | 148 | register struct dinode *ip; |
e19a5dd5 | 149 | { |
5086d197 KM |
150 | register struct direct *dp; |
151 | struct dirstuff dirp; | |
e19a5dd5 | 152 | int k; |
e19a5dd5 KM |
153 | |
154 | if((ip->di_mode&IFMT) != IFDIR) | |
155 | return; | |
5086d197 KM |
156 | dirp.loc = 0; |
157 | dirp.ip = ip; | |
56d45dcd | 158 | gip = ip; |
5086d197 KM |
159 | for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { |
160 | if(dp->d_ino == 0) | |
161 | continue; | |
162 | if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { | |
163 | printf("%d bad; %d/%s\n", | |
164 | dp->d_ino, ino, dp->d_name); | |
165 | nerror++; | |
166 | continue; | |
167 | } | |
168 | for (k = 0; ilist[k] != 0; k++) | |
169 | if (ilist[k] == dp->d_ino) { | |
170 | printf("%d arg; %d/%s\n", | |
171 | dp->d_ino, ino, dp->d_name); | |
e19a5dd5 | 172 | nerror++; |
e19a5dd5 | 173 | } |
5086d197 | 174 | ecount[dp->d_ino]++; |
e19a5dd5 KM |
175 | } |
176 | } | |
177 | ||
178 | pass2(ip) | |
179 | register struct dinode *ip; | |
180 | { | |
181 | register i; | |
182 | ||
183 | i = ino; | |
184 | if ((ip->di_mode&IFMT)==0 && ecount[i]==0) | |
185 | return; | |
186 | if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) | |
187 | return; | |
188 | if (headpr==0) { | |
189 | printf(" entries link cnt\n"); | |
190 | headpr++; | |
191 | } | |
192 | printf("%u\t%d\t%d\n", ino, | |
193 | ecount[i], ip->di_nlink); | |
194 | } | |
195 | ||
5086d197 KM |
196 | /* |
197 | * get next entry in a directory. | |
198 | */ | |
199 | struct direct * | |
200 | readdir(dirp) | |
201 | register struct dirstuff *dirp; | |
202 | { | |
203 | register struct direct *dp; | |
204 | daddr_t lbn, d; | |
205 | ||
206 | for(;;) { | |
207 | if (dirp->loc >= dirp->ip->di_size) | |
208 | return NULL; | |
3352e84a | 209 | if ((lbn = lblkno(&sblock, dirp->loc)) == 0) { |
5086d197 KM |
210 | d = bmap(lbn); |
211 | if(d == 0) | |
212 | return NULL; | |
213 | bread(fsbtodb(&sblock, d), dirp->dbuf, | |
214 | dblksize(&sblock, dirp->ip, lbn)); | |
215 | } | |
216 | dp = (struct direct *) | |
3352e84a | 217 | (dirp->dbuf + blkoff(&sblock, dirp->loc)); |
5086d197 KM |
218 | dirp->loc += dp->d_reclen; |
219 | if (dp->d_ino == 0) | |
220 | continue; | |
221 | return (dp); | |
222 | } | |
223 | } | |
224 | ||
e19a5dd5 KM |
225 | bread(bno, buf, cnt) |
226 | daddr_t bno; | |
227 | char *buf; | |
228 | { | |
229 | register i; | |
230 | ||
a66ab591 | 231 | lseek(fi, bno * dev_bsize, 0); |
e19a5dd5 KM |
232 | if (read(fi, buf, cnt) != cnt) { |
233 | printf("read error %d\n", bno); | |
b6407c9d | 234 | for(i=0; i < cnt; i++) |
e19a5dd5 KM |
235 | buf[i] = 0; |
236 | } | |
237 | } | |
238 | ||
239 | daddr_t | |
240 | bmap(i) | |
241 | { | |
b6407c9d | 242 | daddr_t ibuf[MAXNINDIR]; |
e19a5dd5 KM |
243 | |
244 | if(i < NDADDR) | |
56d45dcd | 245 | return(gip->di_db[i]); |
e19a5dd5 | 246 | i -= NDADDR; |
b6407c9d | 247 | if(i > NINDIR(&sblock)) { |
e19a5dd5 KM |
248 | printf("%u - huge directory\n", ino); |
249 | return((daddr_t)0); | |
250 | } | |
b6407c9d | 251 | bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); |
e19a5dd5 KM |
252 | return(ibuf[i]); |
253 | } |