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: 15: struct filsys sblock; 16: struct dinode itab[INOPB*NI]; 17: daddr_t iaddr[NADDR]; 18: daddr_t blist[NB]; 19: char *bmap; 20: 21: int sflg; 22: int mflg; 23: int dflg; 24: int fi; 25: ino_t ino; 26: 27: ino_t nrfile; 28: ino_t ndfile; 29: ino_t nbfile; 30: ino_t ncfile; 31: 32: daddr_t ndirect; 33: daddr_t nindir; 34: daddr_t niindir; 35: daddr_t niiindir; 36: daddr_t nfree; 37: daddr_t ndup; 38: 39: int nerror; 40: 41: long atol(); 42: daddr_t alloc(); 43: #ifndef STANDALONE 44: char *malloc(); 45: #endif 46: 47: main(argc, argv) 48: char *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: 101: check(file) 102: char *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 = (sblock.s_isize-2) * INOPB; 132: ino = 0; 133: n = (sblock.s_fsize - sblock.s_isize + BITS-1) / BITS; 134: if (n != (unsigned)n) { 135: printf("Check fsize and isize: %ld, %u\n", 136: sblock.s_fsize, 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=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: 218: pass1(ip) 219: register 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: 295: chk(bno, s) 296: daddr_t bno; 297: char *s; 298: { 299: register n; 300: 301: if (bno<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: 315: duped(bno) 316: daddr_t bno; 317: { 318: daddr_t d; 319: register m, n; 320: 321: if(dflg) 322: return(0); 323: d = bno - 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: 332: daddr_t 333: alloc() 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: 368: bfree(bno) 369: daddr_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: 391: bread(bno, buf, cnt) 392: daddr_t bno; 393: char *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: 409: bwrite(bno, buf) 410: daddr_t bno; 411: char *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: 419: makefree() 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 >= 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: }