BSD 3 development
[unix-history] / usr / src / cmd / icheck.c
CommitLineData
7a1fc311
BJ
1#define NI 16
2#define NB 10
3#define BITS 8
4#define MAXFN 500
5
6#ifndef STANDALONE
7#include <stdio.h>
8#endif
9#include <sys/param.h>
10#include <sys/inode.h>
11#include <sys/ino.h>
12#include <sys/fblk.h>
13#include <sys/filsys.h>
14
15struct filsys sblock;
16struct dinode itab[INOPB*NI];
17daddr_t iaddr[NADDR];
18daddr_t blist[NB];
19char *bmap;
20
21int sflg;
22int mflg;
23int dflg;
24int fi;
25ino_t ino;
26
27ino_t nrfile;
28ino_t ndfile;
29ino_t nbfile;
30ino_t ncfile;
31
32daddr_t ndirect;
33daddr_t nindir;
34daddr_t niindir;
35daddr_t niiindir;
36daddr_t nfree;
37daddr_t ndup;
38
39int nerror;
40
41long atol();
42daddr_t alloc();
43#ifndef STANDALONE
44char *malloc();
45#endif
46
47main(argc, argv)
48char *argv[];
49{
50 register i;
51 long n;
52
53 blist[0] = -1;
54#ifndef STANDALONE
55 while (--argc) {
56 argv++;
57 if (**argv=='-')
58 switch ((*argv)[1]) {
59 case 'd':
60 dflg++;
61 continue;
62
63
64 case 'm':
65 mflg++;
66 continue;
67
68 case 's':
69 sflg++;
70 continue;
71
72 case 'b':
73 for(i=0; i<NB; i++) {
74 n = atol(argv[1]);
75 if(n == 0)
76 break;
77 blist[i] = n;
78 argv++;
79 argc--;
80 }
81 blist[i] = -1;
82 continue;
83
84 default:
85 printf("Bad flag\n");
86 }
87 check(*argv);
88 }
89#else
90 {
91 static char fname[0];
92
93 printf("File: ");
94 gets(fname);
95 check(fname);
96 }
97#endif
98 return(nerror);
99}
100
101check(file)
102char *file;
103{
104 register i, j;
105 ino_t mino;
106 daddr_t d;
107 long n;
108
109 fi = open(file, sflg?2:0);
110 if (fi < 0) {
111 printf("cannot open %s\n", file);
112 nerror |= 04;
113 return;
114 }
115 printf("%s:\n", file);
116 nrfile = 0;
117 ndfile = 0;
118 ncfile = 0;
119 nbfile = 0;
120
121 ndirect = 0;
122 nindir = 0;
123 niindir = 0;
124 niiindir = 0;
125
126 ndup = 0;
127#ifndef STANDALONE
128 sync();
129#endif
130 bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
131 mino = ((int)sblock.s_isize-2) * INOPB;
132 ino = 0;
133 n = (sblock.s_fsize - (int)sblock.s_isize + BITS-1) / BITS;
134 if (n != (unsigned)n) {
135 printf("Check fsize and isize: %ld, %u\n",
136 sblock.s_fsize, (int)sblock.s_isize);
137 }
138#ifdef STANDALONE
139 bmap = NULL;
140#else
141 bmap = malloc((unsigned)n);
142#endif
143 if (bmap==NULL) {
144 printf("Not enough core; duplicates unchecked\n");
145 dflg++;
146 sflg = 0;
147 }
148 if(!dflg)
149 for(i=0; i<(unsigned)n; i++)
150 bmap[i] = 0;
151 for(i=2;; i+=NI) {
152 if(ino >= mino)
153 break;
154 bread((daddr_t)i, (char *)itab, sizeof(itab));
155 for(j=0; j<INOPB*NI; j++) {
156 if(ino >= mino)
157 break;
158 ino++;
159 pass1(&itab[j]);
160 }
161 }
162 ino = 0;
163#ifndef STANDALONE
164 sync();
165#endif
166 bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
167 if (sflg) {
168 makefree();
169 close(fi);
170#ifndef STANDALONE
171 if (bmap)
172 free(bmap);
173#endif
174 return;
175 }
176 nfree = 0;
177 while(n = alloc()) {
178 if (chk(n, "free"))
179 break;
180 nfree++;
181 }
182 close(fi);
183#ifndef STANDALONE
184 if (bmap)
185 free(bmap);
186#endif
187
188 i = nrfile + ndfile + ncfile + nbfile;
189#ifndef STANDALONE
190 printf("files %6u (r=%u,d=%u,b=%u,c=%u)\n",
191 i, nrfile, ndfile, nbfile, ncfile);
192#else
193 printf("files %u (r=%u,d=%u,b=%u,c=%u)\n",
194 i, nrfile, ndfile, nbfile, ncfile);
195#endif
196 n = ndirect + nindir + niindir + niindir;
197#ifdef STANDALONE
198 printf("used %ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
199 n, nindir, niindir, niiindir, ndirect);
200 printf("free %ld\n", nfree);
201#else
202 printf("used %7ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
203 n, nindir, niindir, niiindir, ndirect);
204 printf("free %7ld\n", nfree);
205#endif
206 if(!dflg) {
207 n = 0;
208 for(d=(int)sblock.s_isize; d<sblock.s_fsize; d++)
209 if(!duped(d)) {
210 if(mflg)
211 printf("%ld missing\n", d);
212 n++;
213 }
214 printf("missing%5ld\n", n);
215 }
216}
217
218pass1(ip)
219register struct dinode *ip;
220{
221 daddr_t ind1[NINDIR];
222 daddr_t ind2[NINDIR];
223 daddr_t ind3[NINDIR];
224 register i, j;
225 int k, l;
226
227 i = ip->di_mode & IFMT;
228 if(i == 0) {
229 sblock.s_tinode++;
230 return;
231 }
232 if(i == IFCHR) {
233 ncfile++;
234 return;
235 }
236 if(i == IFBLK) {
237 nbfile++;
238 return;
239 }
240 if(i == IFDIR)
241 ndfile++; else
242 if(i == IFREG)
243 nrfile++;
244 else {
245 printf("bad mode %u\n", ino);
246 return;
247 }
248 l3tol(iaddr, ip->di_addr, NADDR);
249 for(i=0; i<NADDR; i++) {
250 if(iaddr[i] == 0)
251 continue;
252 if(i < NADDR-3) {
253 ndirect++;
254 chk(iaddr[i], "data (small)");
255 continue;
256 }
257 nindir++;
258 if (chk(iaddr[i], "1st indirect"))
259 continue;
260 bread(iaddr[i], (char *)ind1, BSIZE);
261 for(j=0; j<NINDIR; j++) {
262 if(ind1[j] == 0)
263 continue;
264 if(i == NADDR-3) {
265 ndirect++;
266 chk(ind1[j], "data (large)");
267 continue;
268 }
269 niindir++;
270 if(chk(ind1[j], "2nd indirect"))
271 continue;
272 bread(ind1[j], (char *)ind2, BSIZE);
273 for(k=0; k<NINDIR; k++) {
274 if(ind2[k] == 0)
275 continue;
276 if(i == NADDR-2) {
277 ndirect++;
278 chk(ind2[k], "data (huge)");
279 continue;
280 }
281 niiindir++;
282 if(chk(ind2[k], "3rd indirect"))
283 continue;
284 bread(ind2[k], (char *)ind3, BSIZE);
285 for(l=0; l<NINDIR; l++)
286 if(ind3[l]) {
287 ndirect++;
288 chk(ind3[l], "data (garg)");
289 }
290 }
291 }
292 }
293}
294
295chk(bno, s)
296daddr_t bno;
297char *s;
298{
299 register n;
300
301 if (bno<(int)sblock.s_isize || bno>=sblock.s_fsize) {
302 printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
303 return(1);
304 }
305 if(duped(bno)) {
306 printf("%ld dup; inode=%u, class=%s\n", bno, ino, s);
307 ndup++;
308 }
309 for (n=0; blist[n] != -1; n++)
310 if (bno == blist[n])
311 printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
312 return(0);
313}
314
315duped(bno)
316daddr_t bno;
317{
318 daddr_t d;
319 register m, n;
320
321 if(dflg)
322 return(0);
323 d = bno - (int)sblock.s_isize;
324 m = 1 << (d%BITS);
325 n = (d/BITS);
326 if(bmap[n] & m)
327 return(1);
328 bmap[n] |= m;
329 return(0);
330}
331
332daddr_t
333alloc()
334{
335 int i;
336 daddr_t bno;
337 union {
338 char data[BSIZE];
339 struct fblk fb;
340 } buf;
341
342 sblock.s_tfree--;
343 if (sblock.s_nfree<=0)
344 return(0);
345 if (sblock.s_nfree>NICFREE) {
346 printf("Bad free list, s.b. count = %d\n", sblock.s_nfree);
347 return(0);
348 }
349 bno = sblock.s_free[--sblock.s_nfree];
350 sblock.s_free[sblock.s_nfree] = (daddr_t)0;
351 if(bno == 0)
352 return(bno);
353 if(sblock.s_nfree <= 0) {
354 bread(bno, buf.data, BSIZE);
355 sblock.s_nfree = buf.df_nfree;
356 if (sblock.s_nfree<0 || sblock.s_nfree>NICFREE) {
357 printf("Bad free list, entry count of block %ld = %d\n",
358 bno, sblock.s_nfree);
359 sblock.s_nfree = 0;
360 return(0);
361 }
362 for(i=0; i<NICFREE; i++)
363 sblock.s_free[i] = buf.df_free[i];
364 }
365 return(bno);
366}
367
368bfree(bno)
369daddr_t bno;
370{
371 union {
372 char data[BSIZE];
373 struct fblk fb;
374 } buf;
375 int i;
376
377 sblock.s_tfree++;
378 if(sblock.s_nfree >= NICFREE) {
379 for(i=0; i<BSIZE; i++)
380 buf.data[i] = 0;
381 buf.df_nfree = sblock.s_nfree;
382 for(i=0; i<NICFREE; i++)
383 buf.df_free[i] = sblock.s_free[i];
384 bwrite(bno, buf.data);
385 sblock.s_nfree = 0;
386 }
387 sblock.s_free[sblock.s_nfree] = bno;
388 sblock.s_nfree++;
389}
390
391bread(bno, buf, cnt)
392daddr_t bno;
393char *buf;
394{
395 register i;
396
397 lseek(fi, bno*BSIZE, 0);
398 if (read(fi, buf, cnt) != cnt) {
399 printf("read error %ld\n", bno);
400 if (sflg) {
401 printf("No update\n");
402 sflg = 0;
403 }
404 for(i=0; i<BSIZE; i++)
405 buf[i] = 0;
406 }
407}
408
409bwrite(bno, buf)
410daddr_t bno;
411char *buf;
412{
413
414 lseek(fi, bno*BSIZE, 0);
415 if (write(fi, buf, BSIZE) != BSIZE)
416 printf("write error %ld\n", bno);
417}
418
419makefree()
420{
421 char flg[MAXFN];
422 int adr[MAXFN];
423 register i, j;
424 daddr_t f, d;
425 int m, n;
426
427 n = sblock.s_n;
428 if(n <= 0 || n > MAXFN)
429 n = MAXFN;
430 sblock.s_n = n;
431 m = sblock.s_m;
432 if(m <= 0 || m > sblock.s_n)
433 m = 3;
434 sblock.s_m = m;
435
436 for(i=0; i<n; i++)
437 flg[i] = 0;
438 i = 0;
439 for(j=0; j<n; j++) {
440 while(flg[i])
441 i = (i+1)%n;
442 adr[j] = i+1;
443 flg[i]++;
444 i = (i+m)%n;
445 }
446
447 sblock.s_nfree = 0;
448 sblock.s_ninode = 0;
449 sblock.s_flock = 0;
450 sblock.s_ilock = 0;
451 sblock.s_fmod = 0;
452 sblock.s_ronly = 0;
453#ifndef STANDALONE
454 time(&sblock.s_time);
455#endif
456 sblock.s_tfree = 0;
457 sblock.s_tinode = 0;
458
459 bfree((daddr_t)0);
460 d = sblock.s_fsize-1;
461 while(d%sblock.s_n)
462 d++;
463 for(; d > 0; d -= sblock.s_n)
464 for(i=0; i<sblock.s_n; i++) {
465 f = d - adr[i];
466 if(f < sblock.s_fsize && f >= (int)sblock.s_isize)
467 if(!duped(f))
468 bfree(f);
469 }
470 bwrite((daddr_t)1, (char *)&sblock);
471#ifndef STANDALONE
472 sync();
473#endif
474 return;
475}