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