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