|
|
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.