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