|
|
1.1 root 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:
7: #ifndef lint
8: static char sccsid[] = "@(#)icheck.c 5.6 (Berkeley) 5/4/90";
9: #endif not lint
10:
11: /*
12: * icheck
13: */
14: #define NB 500
15: #define MAXFN 500
16: #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t))
17:
18: #include <sys/param.h>
19: #include <ufs/dinode.h>
20: #include <ufs/fs.h>
21: #ifndef STANDALONE
22: #include <stdio.h>
23: #endif
24:
25: union {
26: struct fs sb;
27: char pad[SBSIZE];
28: } sbun;
29: #define sblock sbun.sb
30:
31: union {
32: struct cg cg;
33: char pad[MAXBSIZE];
34: } cgun;
35: #define cgrp cgun.cg
36:
37: struct dinode itab[MAXBSIZE / sizeof(struct dinode)];
38:
39: daddr_t blist[NB];
40: daddr_t fsblist[NB];
41: char *bmap;
42:
43: int mflg;
44: int dflg;
45: int fi;
46: ino_t ino;
47: int cginit;
48:
49: ino_t nrfile;
50: ino_t ndfile;
51: ino_t nbfile;
52: ino_t ncfile;
53: ino_t nlfile;
54: ino_t nsfile;
55:
56: daddr_t nblock;
57: daddr_t nfrag;
58: daddr_t nindir;
59: daddr_t niindir;
60:
61: daddr_t nffree;
62: daddr_t nbfree;
63:
64: daddr_t ndup;
65:
66: int nerror;
67: long dev_bsize = 1;
68:
69: long atol();
70: #ifndef STANDALONE
71: char *malloc();
72: char *calloc();
73: #endif
74:
75: main(argc, argv)
76: int argc;
77: char *argv[];
78: {
79: register i;
80: long n;
81:
82: blist[0] = -1;
83: #ifndef STANDALONE
84: while (--argc) {
85: argv++;
86: if (**argv=='-')
87: switch ((*argv)[1]) {
88: case 'd':
89: dflg++;
90: continue;
91:
92: case 'm':
93: mflg++;
94: continue;
95:
96: case 'b':
97: for(i=0; i<NB; i++) {
98: n = atol(argv[1]);
99: if(n == 0)
100: break;
101: blist[i] = n;
102: argv++;
103: argc--;
104: }
105: blist[i] = -1;
106: continue;
107:
108: default:
109: printf("Bad flag\n");
110: }
111: check(*argv);
112: }
113: #else
114: {
115: static char fname[128];
116:
117: printf("File: ");
118: gets(fname);
119: check(fname);
120: }
121: #endif
122: return(nerror);
123: }
124:
125: check(file)
126: char *file;
127: {
128: register i, j, c;
129: daddr_t d, cgd, cbase, b;
130: long n;
131: char buf[BUFSIZ];
132:
133: fi = open(file, 0);
134: if (fi < 0) {
135: perror(file);
136: nerror |= 04;
137: return;
138: }
139: printf("%s:\n", file);
140: nrfile = 0;
141: ndfile = 0;
142: ncfile = 0;
143: nbfile = 0;
144: nlfile = 0;
145: nsfile = 0;
146:
147: nblock = 0;
148: nfrag = 0;
149: nindir = 0;
150: niindir = 0;
151:
152: ndup = 0;
153: #ifndef STANDALONE
154: sync();
155: #endif
156: getsb(&sblock, file);
157: if (nerror)
158: return;
159: for (n=0; blist[n] != -1; n++)
160: fsblist[n] = dbtofsb(&sblock, blist[n]);
161: ino = 0;
162: n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
163: #ifdef STANDALONE
164: bmap = NULL;
165: #else
166: bmap = malloc((unsigned)n);
167: #endif
168: if (bmap==NULL) {
169: printf("Not enough core; duplicates unchecked\n");
170: dflg++;
171: }
172: ino = 0;
173: cginit = 1;
174: if (!dflg) {
175: for (i = 0; i < (unsigned)n; i++)
176: bmap[i] = 0;
177: for (c = 0; c < sblock.fs_ncg; c++) {
178: cgd = cgtod(&sblock, c);
179: if (c == 0)
180: d = cgbase(&sblock, c);
181: else
182: d = cgsblock(&sblock, c);
183: (void)sprintf(buf, "spare super block %d", c);
184: for (; d < cgd; d += sblock.fs_frag)
185: chk(d, buf, sblock.fs_bsize);
186: d = cgimin(&sblock, c);
187: (void)sprintf(buf, "cylinder group %d", c);
188: while (cgd < d) {
189: chk(cgd, buf, sblock.fs_bsize);
190: cgd += sblock.fs_frag;
191: }
192: d = cgdmin(&sblock, c);
193: i = INOPB(&sblock);
194: for (; cgd < d; cgd += sblock.fs_frag) {
195: (void)sprintf(buf, "inodes %d-%d", ino, ino + i);
196: chk(cgd, buf, sblock.fs_bsize);
197: ino += i;
198: }
199: if (c == 0) {
200: d += howmany(sblock.fs_cssize, sblock.fs_fsize);
201: for (; cgd < d; cgd++)
202: chk(cgd, "csum", sblock.fs_fsize);
203: }
204: }
205: }
206: ino = 0;
207: cginit = 0;
208: for (c = 0; c < sblock.fs_ncg; c++) {
209: for (i = 0;
210: i < sblock.fs_ipg / INOPF(&sblock);
211: i += sblock.fs_frag) {
212: bread(fsbtodb(&sblock, cgimin(&sblock, c) + i),
213: (char *)itab, sblock.fs_bsize);
214: for (j = 0; j < INOPB(&sblock); j++) {
215: pass1(&itab[j]);
216: ino++;
217: }
218: }
219: }
220: ino = 0;
221: #ifndef STANDALONE
222: sync();
223: #endif
224: nffree = 0;
225: nbfree = 0;
226: for (c = 0; c < sblock.fs_ncg; c++) {
227: cbase = cgbase(&sblock, c);
228: bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
229: sblock.fs_cgsize);
230: if (!cg_chkmagic(&cgrp))
231: printf("cg %d: bad magic number\n", c);
232: for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
233: if (isblock(&sblock, cg_blksfree(&cgrp),
234: b / sblock.fs_frag)) {
235: nbfree++;
236: chk(cbase+b, "free block", sblock.fs_bsize);
237: } else {
238: for (d = 0; d < sblock.fs_frag; d++)
239: if (isset(cg_blksfree(&cgrp), b+d)) {
240: chk(cbase+b+d, "free frag", sblock.fs_fsize);
241: nffree++;
242: }
243: }
244: }
245: }
246: close(fi);
247: #ifndef STANDALONE
248: if (bmap)
249: free(bmap);
250: #endif
251:
252: i = nrfile + ndfile + ncfile + nbfile + nlfile + nsfile;
253: #ifndef STANDALONE
254: printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u,sock=%u)\n",
255: i, nrfile, ndfile, nbfile, ncfile, nlfile, nsfile);
256: #else
257: printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u,sock=%u)\n",
258: i, nrfile, ndfile, nbfile, ncfile, nlfile, nsfile);
259: #endif
260: n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
261: #ifdef STANDALONE
262: printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
263: n, nindir, niindir, nblock, nfrag);
264: printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
265: nbfree, nffree);
266: #else
267: printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
268: n, nindir, niindir, nblock, nfrag);
269: printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
270: nbfree, nffree);
271: #endif
272: if(!dflg) {
273: n = 0;
274: for (d = 0; d < sblock.fs_size; d++)
275: if(!duped(d, sblock.fs_fsize)) {
276: if(mflg)
277: printf("%ld missing\n", d);
278: n++;
279: }
280: printf("missing%5ld\n", n);
281: }
282: }
283:
284: pass1(ip)
285: register struct dinode *ip;
286: {
287: daddr_t ind1[MAXNINDIR];
288: daddr_t ind2[MAXNINDIR];
289: daddr_t db, ib;
290: register int i, j, k, siz;
291: int lbn;
292: char buf[BUFSIZ];
293:
294: i = ip->di_mode & IFMT;
295: if(i == 0)
296: return;
297: switch (i) {
298: case IFCHR:
299: ncfile++;
300: return;
301: case IFBLK:
302: nbfile++;
303: return;
304: case IFDIR:
305: ndfile++;
306: break;
307: case IFREG:
308: nrfile++;
309: break;
310: case IFSOCK:
311: nsfile++;
312: break;
313: case IFLNK:
314: nlfile++;
315: break;
316: default:
317: printf("bad mode %u\n", ino);
318: return;
319: }
320: for (i = 0; i < NDADDR; i++) {
321: db = ip->di_db[i];
322: if (db == 0)
323: continue;
324: siz = dblksize(&sblock, ip, i);
325: (void)sprintf(buf, "logical data block %d", i);
326: chk(db, buf, siz);
327: if (siz == sblock.fs_bsize)
328: nblock++;
329: else
330: nfrag += howmany(siz, sblock.fs_fsize);
331: }
332: for(i = 0; i < NIADDR; i++) {
333: ib = ip->di_ib[i];
334: if (ib == 0)
335: continue;
336: if (chk(ib, "1st indirect", sblock.fs_bsize))
337: continue;
338: bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
339: nindir++;
340: for (j = 0; j < NINDIR(&sblock); j++) {
341: ib = ind1[j];
342: if (ib == 0)
343: continue;
344: if (i == 0) {
345: lbn = NDADDR + j;
346: siz = dblksize(&sblock, ip, lbn);
347: (void)sprintf(buf, "logical data block %d", lbn);
348: chk(ib, buf, siz);
349: if (siz == sblock.fs_bsize)
350: nblock++;
351: else
352: nfrag += howmany(siz, sblock.fs_fsize);
353: continue;
354: }
355: if (chk(ib, "2nd indirect", sblock.fs_bsize))
356: continue;
357: bread(fsbtodb(&sblock, ib), (char *)ind2,
358: sblock.fs_bsize);
359: niindir++;
360: for (k = 0; k < NINDIR(&sblock); k++) {
361: ib = ind2[k];
362: if (ib == 0)
363: continue;
364: lbn = NDADDR + NINDIR(&sblock) * (i + j) + k;
365: siz = dblksize(&sblock, ip, lbn);
366: (void)sprintf(buf, "logical data block %d", lbn);
367: chk(ib, buf, siz);
368: if (siz == sblock.fs_bsize)
369: nblock++;
370: else
371: nfrag += howmany(siz, sblock.fs_fsize);
372: }
373: }
374: }
375: }
376:
377: chk(bno, s, size)
378: daddr_t bno;
379: char *s;
380: int size;
381: {
382: register n, cg;
383: int frags;
384:
385: cg = dtog(&sblock, bno);
386: if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) {
387: printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
388: return(1);
389: }
390: frags = numfrags(&sblock, size);
391: if (frags == sblock.fs_frag) {
392: if (duped(bno, size)) {
393: printf("%ld dup block; inode=%u, class=%s\n",
394: bno, ino, s);
395: ndup += sblock.fs_frag;
396: }
397: } else {
398: for (n = 0; n < frags; n++) {
399: if (duped(bno + n, sblock.fs_fsize)) {
400: printf("%ld dup frag; inode=%u, class=%s\n",
401: bno, ino, s);
402: ndup++;
403: }
404: }
405: }
406: for (n=0; blist[n] != -1; n++)
407: if (fsblist[n] >= bno && fsblist[n] < bno + frags)
408: printf("%ld arg; frag %d of %d, inode=%u, class=%s\n",
409: blist[n], fsblist[n] - bno, frags, ino, s);
410: return(0);
411: }
412:
413: duped(bno, size)
414: daddr_t bno;
415: int size;
416: {
417: if(dflg)
418: return(0);
419: if (size != sblock.fs_fsize && size != sblock.fs_bsize)
420: printf("bad size %d to duped\n", size);
421: if (size == sblock.fs_fsize) {
422: if (isset(bmap, bno))
423: return(1);
424: setbit(bmap, bno);
425: return (0);
426: }
427: if (bno % sblock.fs_frag != 0)
428: printf("bad bno %d to duped\n", bno);
429: if (isblock(&sblock, bmap, bno/sblock.fs_frag))
430: return (1);
431: setblock(&sblock, bmap, bno/sblock.fs_frag);
432: return(0);
433: }
434:
435: getsb(fs, file)
436: register struct fs *fs;
437: char *file;
438: {
439: int i, j, size;
440:
441: if (bread(SBOFF, fs, SBSIZE)) {
442: printf("bad super block");
443: perror(file);
444: nerror |= 04;
445: return;
446: }
447: if (fs->fs_magic != FS_MAGIC) {
448: printf("%s: bad magic number\n", file);
449: nerror |= 04;
450: return;
451: }
452: dev_bsize = fs->fs_fsize / fsbtodb(fs, 1);
453: for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
454: size = sblock.fs_cssize - i < sblock.fs_bsize ?
455: sblock.fs_cssize - i : sblock.fs_bsize;
456: sblock.fs_csp[j] = (struct csum *)calloc(1, size);
457: bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)),
458: (char *)fs->fs_csp[j], size);
459: }
460: }
461:
462: bread(bno, buf, cnt)
463: daddr_t bno;
464: char *buf;
465: {
466: register i;
467:
468: lseek(fi, bno * dev_bsize, 0);
469: if ((i = read(fi, buf, cnt)) != cnt) {
470: for(i=0; i<sblock.fs_bsize; i++)
471: buf[i] = 0;
472: return (1);
473: }
474: return (0);
475: }
476:
477: /*
478: * check if a block is available
479: */
480: isblock(fs, cp, h)
481: struct fs *fs;
482: unsigned char *cp;
483: int h;
484: {
485: unsigned char mask;
486:
487: switch (fs->fs_frag) {
488: case 8:
489: return (cp[h] == 0xff);
490: case 4:
491: mask = 0x0f << ((h & 0x1) << 2);
492: return ((cp[h >> 1] & mask) == mask);
493: case 2:
494: mask = 0x03 << ((h & 0x3) << 1);
495: return ((cp[h >> 2] & mask) == mask);
496: case 1:
497: mask = 0x01 << (h & 0x7);
498: return ((cp[h >> 3] & mask) == mask);
499: default:
500: #ifdef STANDALONE
501: printf("isblock bad fs_frag %d\n", fs->fs_frag);
502: #else
503: fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
504: #endif
505: return;
506: }
507: }
508:
509: /*
510: * put a block into the map
511: */
512: setblock(fs, cp, h)
513: struct fs *fs;
514: unsigned char *cp;
515: int h;
516: {
517: switch (fs->fs_frag) {
518: case 8:
519: cp[h] = 0xff;
520: return;
521: case 4:
522: cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
523: return;
524: case 2:
525: cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
526: return;
527: case 1:
528: cp[h >> 3] |= (0x01 << (h & 0x7));
529: return;
530: default:
531: #ifdef STANDALONE
532: printf("setblock bad fs_frag %d\n", fs->fs_frag);
533: #else
534: fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
535: #endif
536: return;
537: }
538: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.