Annotation of researchv10no/cmd/icheck.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.