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