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.1 (Berkeley) 5/28/85";
   9: #endif not lint
  10: 
  11: 
  12: /*
  13:  * icheck
  14:  */
  15: #define NB  500
  16: #define MAXFN   500
  17: #define MAXNINDIR   (MAXBSIZE / sizeof (daddr_t))
  18: 
  19: #ifndef STANDALONE
  20: #include <stdio.h>
  21: #endif
  22: #ifndef SIMFS
  23: #include <sys/param.h>
  24: #include <sys/inode.h>
  25: #include <sys/fs.h>
  26: #else
  27: #include "../h/param.h"
  28: #include "../h/inode.h"
  29: #include "../h/fs.h"
  30: #endif
  31: 
  32: union {
  33:     struct  fs sb;
  34:     char pad[MAXBSIZE];
  35: } sbun;
  36: #define sblock sbun.sb
  37: 
  38: union {
  39:     struct  cg cg;
  40:     char pad[MAXBSIZE];
  41: } cgun;
  42: #define cgrp cgun.cg
  43: 
  44: struct  dinode  itab[MAXIPG];
  45: daddr_t blist[NB];
  46: daddr_t fsblist[NB];
  47: char    *bmap;
  48: 
  49: int mflg;
  50: int sflg;
  51: int dflg;
  52: int fi;
  53: ino_t   ino;
  54: int cginit;
  55: 
  56: ino_t   nrfile;
  57: ino_t   ndfile;
  58: ino_t   nbfile;
  59: ino_t   ncfile;
  60: ino_t   nlfile;
  61: 
  62: daddr_t nblock;
  63: daddr_t nfrag;
  64: daddr_t nindir;
  65: daddr_t niindir;
  66: 
  67: daddr_t nffree;
  68: daddr_t nbfree;
  69: 
  70: daddr_t ndup;
  71: 
  72: int nerror;
  73: 
  74: extern int inside[], around[];
  75: extern unsigned char *fragtbl[];
  76: 
  77: long    atol();
  78: #ifndef STANDALONE
  79: char    *malloc();
  80: char    *calloc();
  81: #endif
  82: 
  83: main(argc, argv)
  84:     int argc;
  85:     char *argv[];
  86: {
  87:     register i;
  88:     long n;
  89: 
  90:     blist[0] = -1;
  91: #ifndef STANDALONE
  92:     while (--argc) {
  93:         argv++;
  94:         if (**argv=='-')
  95:         switch ((*argv)[1]) {
  96:         case 'd':
  97:             dflg++;
  98:             continue;
  99: 
 100:         case 'm':
 101:             mflg++;
 102:             continue;
 103: 
 104:         case 's':
 105:             sflg++;
 106:             continue;
 107: 
 108:         case 'b':
 109:             for(i=0; i<NB; i++) {
 110:                 n = atol(argv[1]);
 111:                 if(n == 0)
 112:                     break;
 113:                 blist[i] = n;
 114:                 argv++;
 115:                 argc--;
 116:             }
 117:             blist[i] = -1;
 118:             continue;
 119: 
 120:         default:
 121:             printf("Bad flag\n");
 122:         }
 123:         check(*argv);
 124:     }
 125: #else
 126:     {
 127:         static char fname[128];
 128: 
 129:         printf("File: ");
 130:         gets(fname);
 131:         check(fname);
 132:     }
 133: #endif
 134:     return(nerror);
 135: }
 136: 
 137: check(file)
 138:     char *file;
 139: {
 140:     register i, j, c;
 141:     daddr_t d, cgd, cbase, b;
 142:     long n;
 143:     char buf[BUFSIZ];
 144: 
 145:     fi = open(file, sflg ? 2 : 0);
 146:     if (fi < 0) {
 147:         perror(file);
 148:         nerror |= 04;
 149:         return;
 150:     }
 151:     printf("%s:\n", file);
 152:     nrfile = 0;
 153:     ndfile = 0;
 154:     ncfile = 0;
 155:     nbfile = 0;
 156:     nlfile = 0;
 157: 
 158:     nblock = 0;
 159:     nfrag = 0;
 160:     nindir = 0;
 161:     niindir = 0;
 162: 
 163:     ndup = 0;
 164: #ifndef STANDALONE
 165:     sync();
 166: #endif
 167:     getsb(&sblock, file);
 168:     if (nerror)
 169:         return;
 170:     for (n=0; blist[n] != -1; n++)
 171:         fsblist[n] = dbtofsb(&sblock, blist[n]);
 172:     ino = 0;
 173:     n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
 174: #ifdef STANDALONE
 175:     bmap = NULL;
 176: #else
 177:     bmap = malloc((unsigned)n);
 178: #endif
 179:     if (bmap==NULL) {
 180:         printf("Not enough core; duplicates unchecked\n");
 181:         dflg++;
 182:         if (sflg) {
 183:             printf("No Updates\n");
 184:             sflg = 0;
 185:         }
 186:     }
 187:     ino = 0;
 188:     cginit = 1;
 189:     if (!dflg) {
 190:         for (i = 0; i < (unsigned)n; i++)
 191:             bmap[i] = 0;
 192:         for (c = 0; c < sblock.fs_ncg; c++) {
 193:             cgd = cgtod(&sblock, c);
 194:             if (c == 0)
 195:                 d = cgbase(&sblock, c);
 196:             else
 197:                 d = cgsblock(&sblock, c);
 198:             sprintf(buf, "spare super block %d", c);
 199:             for (; d < cgd; d += sblock.fs_frag)
 200:                 chk(d, buf, sblock.fs_bsize);
 201:             d = cgimin(&sblock, c);
 202:             sprintf(buf, "cylinder group %d", c);
 203:             while (cgd < d) {
 204:                 chk(cgd, buf, sblock.fs_bsize);
 205:                 cgd += sblock.fs_frag;
 206:             }
 207:             d = cgdmin(&sblock, c);
 208:             i = INOPB(&sblock);
 209:             for (; cgd < d; cgd += sblock.fs_frag) {
 210:                 sprintf(buf, "inodes %d-%d", ino, ino + i);
 211:                 chk(cgd, buf, sblock.fs_bsize);
 212:                 ino += i;
 213:             }
 214:             if (c == 0) {
 215:                 d += howmany(sblock.fs_cssize, sblock.fs_fsize);
 216:                 for (; cgd < d; cgd++)
 217:                     chk(cgd, "csum", sblock.fs_fsize);
 218:             }
 219:         }
 220:     }
 221:     ino = 0;
 222:     cginit = 0;
 223:     for (c = 0; c < sblock.fs_ncg; c++) {
 224:         bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
 225:             sblock.fs_ipg * sizeof (struct dinode));
 226:         for (j=0; j < sblock.fs_ipg; j++) {
 227:             pass1(&itab[j]);
 228:             ino++;
 229:         }
 230:     }
 231:     ino = 0;
 232: #ifndef STANDALONE
 233:     sync();
 234: #endif
 235:     if (sflg) {
 236:         makecg();
 237:         close(fi);
 238: #ifndef STANDALONE
 239:         if (bmap)
 240:             free(bmap);
 241: #endif
 242:         return;
 243:     }
 244:     nffree = 0;
 245:     nbfree = 0;
 246:     for (c = 0; c < sblock.fs_ncg; c++) {
 247:         cbase = cgbase(&sblock, c);
 248:         bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp,
 249:             sblock.fs_cgsize);
 250:         if (cgrp.cg_magic != CG_MAGIC)
 251:             printf("cg %d: bad magic number\n", c);
 252:         for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) {
 253:             if (isblock(&sblock, cgrp.cg_free,
 254:                 b / sblock.fs_frag)) {
 255:                 nbfree++;
 256:                 chk(cbase+b, "free block", sblock.fs_bsize);
 257:             } else {
 258:                 for (d = 0; d < sblock.fs_frag; d++)
 259:                     if (isset(cgrp.cg_free, b+d)) {
 260:                         chk(cbase+b+d, "free frag", sblock.fs_fsize);
 261:                         nffree++;
 262:                     }
 263:             }
 264:         }
 265:     }
 266:     close(fi);
 267: #ifndef STANDALONE
 268:     if (bmap)
 269:         free(bmap);
 270: #endif
 271: 
 272:     i = nrfile + ndfile + ncfile + nbfile + nlfile;
 273: #ifndef STANDALONE
 274:     printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
 275:         i, nrfile, ndfile, nbfile, ncfile, nlfile);
 276: #else
 277:     printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n",
 278:         i, nrfile, ndfile, nbfile, ncfile, nlfile);
 279: #endif
 280:     n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag;
 281: #ifdef STANDALONE
 282:     printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
 283:         n, nindir, niindir, nblock, nfrag);
 284:     printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
 285:         nbfree, nffree);
 286: #else
 287:     printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
 288:         n, nindir, niindir, nblock, nfrag);
 289:     printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree,
 290:         nbfree, nffree);
 291: #endif
 292:     if(!dflg) {
 293:         n = 0;
 294:         for (d = 0; d < sblock.fs_size; d++)
 295:             if(!duped(d, sblock.fs_fsize)) {
 296:                 if(mflg)
 297:                     printf("%ld missing\n", d);
 298:                 n++;
 299:             }
 300:         printf("missing%5ld\n", n);
 301:     }
 302: }
 303: 
 304: pass1(ip)
 305:     register struct dinode *ip;
 306: {
 307:     daddr_t ind1[MAXNINDIR];
 308:     daddr_t ind2[MAXNINDIR];
 309:     daddr_t db, ib;
 310:     register int i, j, k, siz;
 311:     int lbn;
 312:     char buf[BUFSIZ];
 313: 
 314:     i = ip->di_mode & IFMT;
 315:     if(i == 0)
 316:         return;
 317:     switch (i) {
 318:     case IFCHR:
 319:         ncfile++;
 320:         return;
 321:     case IFBLK:
 322:         nbfile++;
 323:         return;
 324:     case IFDIR:
 325:         ndfile++;
 326:         break;
 327:     case IFREG:
 328:         nrfile++;
 329:         break;
 330:     case IFLNK:
 331:         nlfile++;
 332:         break;
 333:     default:
 334:         printf("bad mode %u\n", ino);
 335:         return;
 336:     }
 337:     for (i = 0; i < NDADDR; i++) {
 338:         db = ip->di_db[i];
 339:         if (db == 0)
 340:             continue;
 341:         siz = dblksize(&sblock, ip, i);
 342:         sprintf(buf, "logical data block %d", i);
 343:         chk(db, buf, siz);
 344:         if (siz == sblock.fs_bsize)
 345:             nblock++;
 346:         else
 347:             nfrag += howmany(siz, sblock.fs_fsize);
 348:     }
 349:     for(i = 0; i < NIADDR; i++) {
 350:         ib = ip->di_ib[i];
 351:         if (ib == 0)
 352:             continue;
 353:         if (chk(ib, "1st indirect", sblock.fs_bsize))
 354:             continue;
 355:         bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize);
 356:         nindir++;
 357:         for (j = 0; j < NINDIR(&sblock); j++) {
 358:             ib = ind1[j];
 359:             if (ib == 0)
 360:                 continue;
 361:             if (i == 0) {
 362:                 lbn = NDADDR + j;
 363:                 siz = dblksize(&sblock, ip, lbn);
 364:                 sprintf(buf, "logical data block %d", lbn);
 365:                 chk(ib, buf, siz);
 366:                 if (siz == sblock.fs_bsize)
 367:                     nblock++;
 368:                 else
 369:                     nfrag += howmany(siz, sblock.fs_fsize);
 370:                 continue;
 371:             }
 372:             if (chk(ib, "2nd indirect", sblock.fs_bsize))
 373:                 continue;
 374:             bread(fsbtodb(&sblock, ib), (char *)ind2,
 375:                 sblock.fs_bsize);
 376:             niindir++;
 377:             for (k = 0; k < NINDIR(&sblock); k++) {
 378:                 ib = ind2[k];
 379:                 if (ib == 0)
 380:                     continue;
 381:                 lbn = NDADDR + NINDIR(&sblock) * (i + j) + k;
 382:                 siz = dblksize(&sblock, ip, lbn);
 383:                 sprintf(buf, "logical data block %d", lbn);
 384:                 chk(ib, buf, siz);
 385:                 if (siz == sblock.fs_bsize)
 386:                     nblock++;
 387:                 else
 388:                     nfrag += howmany(siz, sblock.fs_fsize);
 389:             }
 390:         }
 391:     }
 392: }
 393: 
 394: chk(bno, s, size)
 395:     daddr_t bno;
 396:     char *s;
 397:     int size;
 398: {
 399:     register n, cg;
 400:     int frags;
 401: 
 402:     cg = dtog(&sblock, bno);
 403:     if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) {
 404:         printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
 405:         return(1);
 406:     }
 407:     frags = numfrags(&sblock, size);
 408:     if (frags == sblock.fs_frag) {
 409:         if (duped(bno, size)) {
 410:             printf("%ld dup block; inode=%u, class=%s\n",
 411:                 bno, ino, s);
 412:             ndup += sblock.fs_frag;
 413:         }
 414:     } else {
 415:         for (n = 0; n < frags; n++) {
 416:             if (duped(bno + n, sblock.fs_fsize)) {
 417:                 printf("%ld dup frag; inode=%u, class=%s\n",
 418:                     bno, ino, s);
 419:                 ndup++;
 420:             }
 421:         }
 422:     }
 423:     for (n=0; blist[n] != -1; n++)
 424:         if (fsblist[n] >= bno && fsblist[n] < bno + frags)
 425:             printf("%ld arg; frag %d of %d, inode=%u, class=%s\n",
 426:                 blist[n], fsblist[n] - bno, frags, ino, s);
 427:     return(0);
 428: }
 429: 
 430: duped(bno, size)
 431:     daddr_t bno;
 432:     int size;
 433: {
 434:     if(dflg)
 435:         return(0);
 436:     if (size != sblock.fs_fsize && size != sblock.fs_bsize)
 437:         printf("bad size %d to duped\n", size);
 438:     if (size == sblock.fs_fsize) {
 439:         if (isset(bmap, bno))
 440:             return(1);
 441:         setbit(bmap, bno);
 442:         return (0);
 443:     }
 444:     if (bno % sblock.fs_frag != 0)
 445:         printf("bad bno %d to duped\n", bno);
 446:     if (isblock(&sblock, bmap, bno/sblock.fs_frag))
 447:         return (1);
 448:     setblock(&sblock, bmap, bno/sblock.fs_frag);
 449:     return(0);
 450: }
 451: 
 452: makecg()
 453: {
 454:     int c, blk;
 455:     daddr_t dbase, d, dlower, dupper, dmax;
 456:     long i, j, s;
 457:     register struct csum *cs;
 458:     register struct dinode *dp;
 459: 
 460:     sblock.fs_cstotal.cs_nbfree = 0;
 461:     sblock.fs_cstotal.cs_nffree = 0;
 462:     sblock.fs_cstotal.cs_nifree = 0;
 463:     sblock.fs_cstotal.cs_ndir = 0;
 464:     for (c = 0; c < sblock.fs_ncg; c++) {
 465:         dbase = cgbase(&sblock, c);
 466:         dmax = dbase + sblock.fs_fpg;
 467:         if (dmax > sblock.fs_size) {
 468:             for ( ; dmax >= sblock.fs_size; dmax--)
 469:                 clrbit(cgrp.cg_free, dmax - dbase);
 470:             dmax++;
 471:         }
 472:         dlower = cgsblock(&sblock, c) - dbase;
 473:         dupper = cgdmin(&sblock, c) - dbase;
 474:         cs = &sblock.fs_cs(&sblock, c);
 475:         cgrp.cg_time = time(0);
 476:         cgrp.cg_magic = CG_MAGIC;
 477:         cgrp.cg_cgx = c;
 478:         if (c == sblock.fs_ncg - 1)
 479:             cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg;
 480:         else
 481:             cgrp.cg_ncyl = sblock.fs_cpg;
 482:         cgrp.cg_niblk = sblock.fs_ipg;
 483:         cgrp.cg_ndblk = dmax - dbase;
 484:         cgrp.cg_cs.cs_ndir = 0;
 485:         cgrp.cg_cs.cs_nffree = 0;
 486:         cgrp.cg_cs.cs_nbfree = 0;
 487:         cgrp.cg_cs.cs_nifree = 0;
 488:         cgrp.cg_rotor = 0;
 489:         cgrp.cg_frotor = 0;
 490:         cgrp.cg_irotor = 0;
 491:         for (i = 0; i < sblock.fs_frag; i++)
 492:             cgrp.cg_frsum[i] = 0;
 493:         bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
 494:               sblock.fs_ipg * sizeof(struct dinode));
 495:         for (i = 0; i < sblock.fs_ipg; i++) {
 496:             cgrp.cg_cs.cs_nifree++;
 497:             clrbit(cgrp.cg_iused, i);
 498:             dp = &itab[i];
 499:             if ((dp->di_mode & IFMT) != 0) {
 500:                 if ((dp->di_mode & IFMT) == IFDIR)
 501:                     cgrp.cg_cs.cs_ndir++;
 502:                 cgrp.cg_cs.cs_nifree--;
 503:                 setbit(cgrp.cg_iused, i);
 504:                 continue;
 505:             }
 506:         }
 507:         while (i < MAXIPG) {
 508:             clrbit(cgrp.cg_iused, i);
 509:             i++;
 510:         }
 511:         if (c == 0)
 512:             for (i = 0; i < ROOTINO; i++) {
 513:                 setbit(cgrp.cg_iused, i);
 514:                 cgrp.cg_cs.cs_nifree--;
 515:             }
 516:         for (s = 0; s < MAXCPG; s++) {
 517:             cgrp.cg_btot[s] = 0;
 518:             for (i = 0; i < NRPOS; i++)
 519:                 cgrp.cg_b[s][i] = 0;
 520:         }
 521:         if (c == 0) {
 522:             dupper += howmany(sblock.fs_cssize, sblock.fs_fsize);
 523:         }
 524:         for (d = dlower; d < dupper; d++)
 525:             clrbit(cgrp.cg_free, d);
 526:         for (d = 0; (d + sblock.fs_frag) <= dmax - dbase;
 527:             d += sblock.fs_frag) {
 528:             j = 0;
 529:             for (i = 0; i < sblock.fs_frag; i++) {
 530:                 if (!isset(bmap, dbase + d + i)) {
 531:                     setbit(cgrp.cg_free, d + i);
 532:                     j++;
 533:                 } else
 534:                     clrbit(cgrp.cg_free, d+i);
 535:             }
 536:             if (j == sblock.fs_frag) {
 537:                 cgrp.cg_cs.cs_nbfree++;
 538:                 cgrp.cg_btot[cbtocylno(&sblock, d)]++;
 539:                 cgrp.cg_b[cbtocylno(&sblock, d)]
 540:                     [cbtorpos(&sblock, d)]++;
 541:             } else if (j > 0) {
 542:                 cgrp.cg_cs.cs_nffree += j;
 543:                 blk = blkmap(&sblock, cgrp.cg_free, d);
 544:                 fragacct(&sblock, blk, cgrp.cg_frsum, 1);
 545:             }
 546:         }
 547:         for (j = d; d < dmax - dbase; d++) {
 548:             if (!isset(bmap, dbase + d)) {
 549:                 setbit(cgrp.cg_free, d);
 550:                 cgrp.cg_cs.cs_nffree++;
 551:             } else
 552:                 clrbit(cgrp.cg_free, d);
 553:         }
 554:         for (; d % sblock.fs_frag != 0; d++)
 555:             clrbit(cgrp.cg_free, d);
 556:         if (j != d) {
 557:             blk = blkmap(&sblock, cgrp.cg_free, j);
 558:             fragacct(&sblock, blk, cgrp.cg_frsum, 1);
 559:         }
 560:         for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++)
 561:             clrblock(&sblock, cgrp.cg_free, d);
 562:         sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
 563:         sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
 564:         sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
 565:         sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir;
 566:         *cs = cgrp.cg_cs;
 567:         bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp,
 568:             sblock.fs_cgsize);
 569:     }
 570:     for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
 571:         bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
 572:             (char *)sblock.fs_csp[j],
 573:             sblock.fs_cssize - i < sblock.fs_bsize ?
 574:             sblock.fs_cssize - i : sblock.fs_bsize);
 575:     }
 576:     sblock.fs_ronly = 0;
 577:     sblock.fs_fmod = 0;
 578:     bwrite(SBLOCK, (char *)&sblock, SBSIZE);
 579: }
 580: 
 581: /*
 582:  * update the frsum fields to reflect addition or deletion
 583:  * of some frags
 584:  */
 585: fragacct(fs, fragmap, fraglist, cnt)
 586:     struct fs *fs;
 587:     int fragmap;
 588:     long fraglist[];
 589:     int cnt;
 590: {
 591:     int inblk;
 592:     register int field, subfield;
 593:     register int siz, pos;
 594: 
 595:     inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1);
 596:     fragmap <<= 1;
 597:     for (siz = 1; siz < fs->fs_frag; siz++) {
 598:         if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0)
 599:             continue;
 600:         field = around[siz];
 601:         subfield = inside[siz];
 602:         for (pos = siz; pos <= fs->fs_frag; pos++) {
 603:             if ((fragmap & field) == subfield) {
 604:                 fraglist[siz] += cnt;
 605:                 pos += siz;
 606:                 field <<= siz;
 607:                 subfield <<= siz;
 608:             }
 609:             field <<= 1;
 610:             subfield <<= 1;
 611:         }
 612:     }
 613: }
 614: 
 615: getsb(fs, file)
 616:     register struct fs *fs;
 617:     char *file;
 618: {
 619:     int i, j, size;
 620: 
 621:     if (bread(SBLOCK, fs, SBSIZE)) {
 622:         printf("bad super block");
 623:         perror(file);
 624:         nerror |= 04;
 625:         return;
 626:     }
 627:     if (fs->fs_magic != FS_MAGIC) {
 628:         printf("%s: bad magic number\n", file);
 629:         nerror |= 04;
 630:         return;
 631:     }
 632:     for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
 633:         size = sblock.fs_cssize - i < sblock.fs_bsize ?
 634:             sblock.fs_cssize - i : sblock.fs_bsize;
 635:         sblock.fs_csp[j] = (struct csum *)calloc(1, size);
 636:         bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)),
 637:               (char *)fs->fs_csp[j], size);
 638:     }
 639: }
 640: 
 641: bwrite(blk, buf, size)
 642:     char *buf;
 643:     daddr_t blk;
 644:     register size;
 645: {
 646:     if (lseek(fi, blk * DEV_BSIZE, 0) < 0) {
 647:         perror("FS SEEK");
 648:         return(1);
 649:     }
 650:     if (write(fi, buf, size) != size) {
 651:         perror("FS WRITE");
 652:         return(1);
 653:     }
 654:     return (0);
 655: }
 656: 
 657: bread(bno, buf, cnt)
 658:     daddr_t bno;
 659:     char *buf;
 660: {
 661:     register i;
 662: 
 663:     lseek(fi, bno * DEV_BSIZE, 0);
 664:     if ((i = read(fi, buf, cnt)) != cnt) {
 665:         if (sflg) {
 666:             printf("No Update\n");
 667:             sflg = 0;
 668:         }
 669:         for(i=0; i<sblock.fs_bsize; i++)
 670:             buf[i] = 0;
 671:         return (1);
 672:     }
 673:     return (0);
 674: }
 675: 
 676: /*
 677:  * check if a block is available
 678:  */
 679: isblock(fs, cp, h)
 680:     struct fs *fs;
 681:     unsigned char *cp;
 682:     int h;
 683: {
 684:     unsigned char mask;
 685: 
 686:     switch (fs->fs_frag) {
 687:     case 8:
 688:         return (cp[h] == 0xff);
 689:     case 4:
 690:         mask = 0x0f << ((h & 0x1) << 2);
 691:         return ((cp[h >> 1] & mask) == mask);
 692:     case 2:
 693:         mask = 0x03 << ((h & 0x3) << 1);
 694:         return ((cp[h >> 2] & mask) == mask);
 695:     case 1:
 696:         mask = 0x01 << (h & 0x7);
 697:         return ((cp[h >> 3] & mask) == mask);
 698:     default:
 699: #ifdef STANDALONE
 700:         printf("isblock bad fs_frag %d\n", fs->fs_frag);
 701: #else
 702:         fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
 703: #endif
 704:         return;
 705:     }
 706: }
 707: 
 708: /*
 709:  * take a block out of the map
 710:  */
 711: clrblock(fs, cp, h)
 712:     struct fs *fs;
 713:     unsigned char *cp;
 714:     int h;
 715: {
 716:     switch ((fs)->fs_frag) {
 717:     case 8:
 718:         cp[h] = 0;
 719:         return;
 720:     case 4:
 721:         cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
 722:         return;
 723:     case 2:
 724:         cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
 725:         return;
 726:     case 1:
 727:         cp[h >> 3] &= ~(0x01 << (h & 0x7));
 728:         return;
 729:     default:
 730: #ifdef STANDALONE
 731:         printf("clrblock bad fs_frag %d\n", fs->fs_frag);
 732: #else
 733:         fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
 734: #endif
 735:         return;
 736:     }
 737: }
 738: 
 739: /*
 740:  * put a block into the map
 741:  */
 742: setblock(fs, cp, h)
 743:     struct fs *fs;
 744:     unsigned char *cp;
 745:     int h;
 746: {
 747:     switch (fs->fs_frag) {
 748:     case 8:
 749:         cp[h] = 0xff;
 750:         return;
 751:     case 4:
 752:         cp[h >> 1] |= (0x0f << ((h & 0x1) << 2));
 753:         return;
 754:     case 2:
 755:         cp[h >> 2] |= (0x03 << ((h & 0x3) << 1));
 756:         return;
 757:     case 1:
 758:         cp[h >> 3] |= (0x01 << (h & 0x7));
 759:         return;
 760:     default:
 761: #ifdef STANDALONE
 762:         printf("setblock bad fs_frag %d\n", fs->fs_frag);
 763: #else
 764:         fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
 765: #endif
 766:         return;
 767:     }
 768: }
 769: 
 770: /*	tables.c	4.1	82/03/25	*/
 771: 
 772: /* merged into kernel:	tables.c 2.1 3/25/82 */
 773: 
 774: /* last monet version:	partab.c	4.2	81/03/08	*/
 775: 
 776: /*
 777:  * bit patterns for identifying fragments in the block map
 778:  * used as ((map & around) == inside)
 779:  */
 780: int around[9] = {
 781:     0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
 782: };
 783: int inside[9] = {
 784:     0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe
 785: };
 786: 
 787: /*
 788:  * given a block map bit pattern, the frag tables tell whether a
 789:  * particular size fragment is available.
 790:  *
 791:  * used as:
 792:  * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] {
 793:  *	at least one fragment of the indicated size is available
 794:  * }
 795:  *
 796:  * These tables are used by the scanc instruction on the VAX to
 797:  * quickly find an appropriate fragment.
 798:  */
 799: 
 800: unsigned char fragtbl124[256] = {
 801:     0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e,
 802:     0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a,
 803:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 804:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 805:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 806:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 807:     0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
 808:     0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
 809:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 810:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 811:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 812:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 813:     0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e,
 814:     0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae,
 815:     0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
 816:     0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
 817:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 818:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 819:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 820:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 821:     0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e,
 822:     0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e,
 823:     0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
 824:     0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
 825:     0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e,
 826:     0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa,
 827:     0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e,
 828:     0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe,
 829:     0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e,
 830:     0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce,
 831:     0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce,
 832:     0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a,
 833: };
 834: 
 835: unsigned char fragtbl8[256] = {
 836:     0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04,
 837:     0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08,
 838:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 839:     0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10,
 840:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 841:     0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
 842:     0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
 843:     0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20,
 844:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 845:     0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
 846:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 847:     0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
 848:     0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
 849:     0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
 850:     0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
 851:     0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40,
 852:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 853:     0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
 854:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 855:     0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11,
 856:     0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05,
 857:     0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09,
 858:     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
 859:     0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21,
 860:     0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06,
 861:     0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a,
 862:     0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07,
 863:     0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12,
 864:     0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04,
 865:     0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c,
 866:     0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c,
 867:     0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80,
 868: };
 869: 
 870: /*
 871:  * the actual fragtbl array
 872:  */
 873: unsigned char *fragtbl[MAXFRAG + 1] = {
 874:     0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
 875: };

Defined functions

bread defined in line 657; used 7 times
bwrite defined in line 641; used 3 times
check defined in line 137; used 2 times
chk defined in line 394; used 11 times
clrblock defined in line 711; used 1 times
duped defined in line 430; used 3 times
fragacct defined in line 585; used 2 times
getsb defined in line 615; used 1 times
isblock defined in line 679; used 2 times
main defined in line 83; never used
makecg defined in line 452; used 1 times
pass1 defined in line 304; used 1 times
setblock defined in line 742; used 1 times

Defined variables

around declared in line 74; defined in line 780; used 2 times
bmap defined in line 47; used 14 times
cginit defined in line 54; used 3 times
dflg defined in line 51; used 5 times
fi defined in line 52; used 8 times
fragtbl declared in line 75; defined in line 873; used 2 times
fragtbl124 defined in line 800; used 3 times
  • in line 874(3)
fragtbl8 defined in line 835; used 1 times
inside declared in line 74; defined in line 783; used 2 times
itab defined in line 44; used 4 times
mflg defined in line 49; used 2 times
nerror defined in line 72; used 5 times
sccsid defined in line 8; never used
sflg defined in line 50; used 7 times

Defined macros

MAXFN defined in line 16; never used
MAXNINDIR defined in line 17; used 2 times
NB defined in line 15; used 3 times
cgrp defined in line 42; used 52 times
sblock defined in line 36; used 142 times
Last modified: 1985-06-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2274
Valid CSS Valid XHTML 1.0 Strict