Annotation of researchv10no/cmd/chuck/check.c, revision 1.1

1.1     ! root        1: #include "fs.h"
        !             2: #include "sys/fblk.h"
        !             3: enum {Byte=8}; /* number of bits per byte */
        !             4: int btypes[NADDR] = {Data, Data, Data, Data, Data, Data, Data, Data, Data, Data,
        !             5:                Ind, Ind2, Ind3};
        !             6: int dtypes[NADDR] = {First, Other, Other, Other, Other, Other, Other, Other,
        !             7:                Other, Other, Ind, Ind2, Ind3};
        !             8: 
        !             9: firstsuper()
        !            10: {      int i;
        !            11:        if(bread(1, (char *)&sblk, 1)) {
        !            12:                perror("superblock");
        !            13:                fatal("couldn't read superblock of %s\n", file);
        !            14:        }
        !            15:        inopb = bsize / sizeof(struct dinode);
        !            16:        ninode = (sblk.s_isize-2) * inopb + 1;
        !            17:        fblk = sblk.s_isize;
        !            18:        pblk = sblk.s_fsize;
        !            19:        if(bsize >= 4096 && BITMAP*Byte*sizeof(long)+fblk < pblk) {
        !            20:                i = (pblk + (bsize*Byte-1))/(bsize*Byte);
        !            21:                lblk = pblk - i;
        !            22:        }
        !            23:        else
        !            24:                lblk = pblk;
        !            25:        if(flags['v'])
        !            26:                pmesg("ninode %d isize %d lblk %d pblk %d\n", ninode, fblk, lblk,
        !            27:                        pblk);
        !            28:        if(ninode < 2 || lblk <= fblk || pblk < lblk)
        !            29:                fatal("absurd(%d inodes, lblk=%d, pblk=%d)\n", ninode, fblk, pblk);
        !            30:        /* allocate all the space */
        !            31:        buf = (char *) malloc(buflen = fblk * bsize);
        !            32:        if(!buf)        /* we've been too greedy, cache this stuff FIX*/
        !            33:                fatal("couldn't alloc %d bytes for buffers\n", buflen);
        !            34:        imap = (im *) malloc(ninode*sizeof(im));
        !            35:        bmap = (bm *) malloc(pblk*sizeof(bm));
        !            36:        dmap = (dm *) malloc((dmaplen = 1000)*sizeof(dm));
        !            37:        if(!imap || !bmap || !dmap)
        !            38:                fatal("couldn't alloc imap, bmap, or dmap\n");
        !            39:        memset((char *)imap, 0, ninode*sizeof(im));
        !            40:        memset((char *)bmap, 0, pblk*sizeof(bm));
        !            41:        if(flags['v'])
        !            42:                pmesg("alloc: %d for bufs, %d for imap, %d for bmap\n", buflen,
        !            43:                        ninode*sizeof(im), pblk*sizeof(bm));
        !            44:        timer("alloc");
        !            45:        if(bread(0, buf, fblk)) /* fragile, FIX */
        !            46:                fatal("couldn't read inodes\n");
        !            47:        bmap[0].type = Boot;
        !            48:        bmap[1].type = Sblock;
        !            49:        for(i = 2; i < fblk; i++)
        !            50:                bmap[i].type = Inode;
        !            51:        /* and, if necessary, the extra bitmaps */
        !            52:        if(pblk > lblk) {
        !            53:                freeb = (char *) malloc(bsize * (pblk-lblk));
        !            54:                if(!freeb || bread(lblk, freeb, pblk-lblk))
        !            55:                        fatal("couldn't read bitmap blocks\n");
        !            56:                for(i = lblk; i < pblk; i++)
        !            57:                        bmap[i].type = Bits;
        !            58:        }
        !            59: }
        !            60: 
        !            61: scaninodes()
        !            62: {      register int ino, *lp, *p;
        !            63:        register struct dinode *dp;
        !            64:        register im *ip;
        !            65:        register bm *bp;
        !            66:        int addr[NADDR], *ty, last;
        !            67:        ino = 0;
        !            68:        ip = imap+1;
        !            69:        dp = (struct dinode *) (buf+2*bsize);
        !            70:        for(ino = 1; ino < ninode; ino++, dp++, ip++) {
        !            71:                switch(dp->di_mode & IFMT) {
        !            72:                default:
        !            73:                        pmesg("ino %d weird mode 0%o\n", ino, dp->di_mode);
        !            74:                        ip->type = Weird;
        !            75:                        continue;
        !            76:                case IFDIR:
        !            77:                        ip->type = Dir;
        !            78:                        ty = dtypes;
        !            79:                        break;
        !            80:                case IFCHR:
        !            81:                        ip->type = Chr;
        !            82:                        continue;
        !            83:                case IFBLK:
        !            84:                        ip->type = Blk;
        !            85:                        continue;
        !            86:                case IFREG:
        !            87:                        ip->type = Reg;
        !            88:                        ty = btypes;
        !            89:                        break;
        !            90:                case IFLNK:
        !            91:                        ty = btypes;
        !            92:                        ip->type = Lnk;
        !            93:                        if(dp->di_size > bsize || dp->di_size == 0)
        !            94:                                inoerr(Elinksize, ino);
        !            95:                        break;
        !            96:                case 0:
        !            97:                        if(!dp->di_mode && !dp->di_size && !dp->di_nlink)
        !            98:                                ip->type = Unalloc;
        !            99:                        else
        !           100:                                ip->type = Weird;
        !           101:                        continue;
        !           102:                }
        !           103:                /* now look through the blocks in the inode */
        !           104:                l3tol(addr, dp->di_addr, NADDR);
        !           105:                p = addr;
        !           106:                lp = addr + NADDR;
        !           107:                for(last = -1; p < lp; p++) {
        !           108:                        if(*p == 0)
        !           109:                                continue;
        !           110:                        if(*p < fblk || *p >= lblk) {
        !           111:                                inoerr(Ebadaddr, ino, *p);
        !           112:                                continue;
        !           113:                        }
        !           114:                        bp = bmap + *p;
        !           115:                        if(bp->ino)
        !           116:                                dupblock(bp, bp->type, 0);
        !           117:                        bp->ino = ino;
        !           118:                        bp->type = ty[p-addr];
        !           119:                        blkcnts[bp->type]++;
        !           120:                        last = p-addr;
        !           121:                        switch(last) {
        !           122:                        case 10:        /* indirect */
        !           123:                                bp->bnum = NADDR-3;
        !           124:                                continue;
        !           125:                        case 11:
        !           126:                                bp->bnum = bsize/sizeof(long) + NADDR-3;
        !           127:                                continue;
        !           128:                        /* hard to tell if triple blocks are an error, so... */
        !           129:                        case 12:
        !           130:                                if(bsize >= 4096)
        !           131:                                        bp->type = Other, inoerr(Etriple, ino, *p);
        !           132:                                else
        !           133:                                        bp->bnum = (bsize/sizeof(long)) *
        !           134:                                                (bsize/sizeof(long) + 1) + NADDR-3;
        !           135:                                continue;
        !           136:                        }
        !           137:                }
        !           138:                if(ip->type == Dir && (addr[0] < fblk || addr[0] >= lblk))
        !           139:                        direrror(Efirst, ino);
        !           140:                ip->last = last;
        !           141:        }
        !           142: }
        !           143: 
        !           144: indblocks(old, new)
        !           145: register old;
        !           146: {      register int *p, *ep;
        !           147:        register bm *bp, *obp, *mx = bmap + lblk;
        !           148:        int nty, delta, last;
        !           149: 
        !           150:        switch(old) {
        !           151:        default:
        !           152:                delta = 1;
        !           153:                break;
        !           154:        case Ind2:
        !           155:                delta = bsize/sizeof(long);
        !           156:                break;
        !           157:        case Ind3:
        !           158:                delta = bsize/sizeof(long) * bsize/sizeof(long);
        !           159:                break;
        !           160:        }
        !           161:        ep = (int *)(buf+bsize);
        !           162:        for(obp = bmap+1; obp < mx; obp++) {
        !           163:                if(obp->type != old)
        !           164:                        continue;
        !           165:                if(bread(obp-bmap, buf, 1)) {
        !           166:                        pmesg("ino %d block %d couldn't read\n", obp->ino,
        !           167:                                obp-bmap);
        !           168:                        obp->type = Ioerr;
        !           169:                        inoerr(Ebadread, obp->ino, obp-bmap);
        !           170:                        continue;
        !           171:                }
        !           172:                nty = obp->type == Dir && new == Data? Other: new;
        !           173:                for(last = -1, p = (long *)buf; p < ep; p++) {
        !           174:                        if(*p == 0)
        !           175:                                continue;
        !           176:                        if(*p < fblk || *p >= lblk) {
        !           177:                                inoerr(Ebadaddr, bmap[obp-bmap].ino);
        !           178:                                break;
        !           179:                        }
        !           180:                        bp = bmap + *p;
        !           181:                        if(bp->ino)
        !           182:                                dupblock(bp, obp->type, new);
        !           183:                        last = bp->bnum = obp->bnum + delta*(p-(long *)buf);
        !           184:                        bp->ino = obp->ino;
        !           185:                        bp->type = nty;
        !           186:                        blkcnts[nty]++;
        !           187:                }
        !           188:                if(last == -1)
        !           189:                        pmesg("ino %d had ind block (%d) all 0\n", obp->ino,
        !           190:                                obp-bmap);
        !           191:                if(imap[obp->ino].last < last)
        !           192:                        imap[obp->ino].last = last;
        !           193:        }
        !           194: }
        !           195: 
        !           196: dochecks()
        !           197: {      int i, j, k;
        !           198:        im *ip = imap + ROOTINO;
        !           199:        struct dinode *dp = (struct dinode *)(buf + 2*bsize);
        !           200:        for(i = ROOTINO, dp += i-1; i < ninode; i++, ip++, dp++) {
        !           201:                j = dp->di_nlink;
        !           202:                if(ip->type != Unalloc && ip->nrefs == 0 && j == 0)
        !           203:                        inoerr(Enullable, i, 0);
        !           204:                else if(ip->nrefs != j)
        !           205:                        inoerr(Elinkcnt, i, ip->nrefs-j);
        !           206:                switch(ip->type) {
        !           207:                case Dir:
        !           208:                        if(dp->di_size < 32)    /* no room for . and .. */
        !           209:                                direrror(Eshortdir, i, dp->di_size);
        !           210:                case Lnk: case Reg:
        !           211:                        k = ip->last;
        !           212:                        if(dp->di_size == 0 && k == -1)
        !           213:                                continue;
        !           214:                        j = (dp->di_size-1)/bsize;
        !           215:                        if(j == k)
        !           216:                                continue;
        !           217:                        if(j < k)       /* blks after end */
        !           218:                                inoerr(Eshort, i, k);
        !           219:                        if(j > k)       /* ends with holes */
        !           220:                                inoerr(Ehole, i, k);
        !           221:                }       
        !           222:        }
        !           223:        dirtree();
        !           224: }
        !           225: 
        !           226: checksuper()
        !           227: {      register int i, cnt, j, k;
        !           228:        bm *bp;
        !           229:        int last;
        !           230:        if(!sblk.U.B.S_valid)
        !           231:                supererr(Einvalid, 0, 0);
        !           232:        for(cnt = i = 0; i < NICINOD && i < sblk.s_ninode; i++) {
        !           233:                j = sblk.s_inode[i];
        !           234:                if(j == 0)      /* really? */
        !           235:                        continue;
        !           236:                if(j >= ninode || imap[j].type != Unalloc) {
        !           237:                        supererr(Esuperino, j, 0);
        !           238:                        break;
        !           239:                }
        !           240:                cnt++;
        !           241:        }
        !           242:        if(i >= NICINOD && cnt != sblk.s_ninode)
        !           243:                supererr(Esuperino, 0, cnt);
        !           244:        for(i = 1, cnt = 0; i < ninode; i++)
        !           245:                if(imap[i].type == Unalloc)
        !           246:                        cnt++;
        !           247:        tinode = cnt;
        !           248:        if(cnt != sblk.s_tinode)
        !           249:                supererr(Esuperino, cnt, sblk.s_tinode);
        !           250:        if(bsize < 4096) {      /* there should be a file system type FIX */
        !           251:                ch1free();
        !           252:                return;
        !           253:        }
        !           254:        if(pblk > lblk) {
        !           255:                chbitmap();
        !           256:                return;
        !           257:        }
        !           258:        cnt = fblk;
        !           259:        bp = bmap + cnt;
        !           260:        for(i = 0; i < BITMAP; i++, cnt += 32) {
        !           261:                k = sblk.U.B.S_bfree[i];
        !           262:                for(j = 0; j < 32; j++, bp++) {
        !           263:                        if((k & (1<<j)) == 0) {
        !           264:                                continue;
        !           265:                        }
        !           266:                        if(cnt+j >= lblk) {
        !           267:                                supererr(Esuperfree, cnt+j, 0);
        !           268:                                return;
        !           269:                        }
        !           270:                        if(bp->type == Unk) {
        !           271:                                bp->type = Free;
        !           272:                                blkcnts[Free]++;
        !           273:                        }
        !           274:                        else {
        !           275:                                supererr(Esuperfree, cnt+j, bp->type);
        !           276:                                return;
        !           277:                        }
        !           278:                }
        !           279:        }
        !           280:        for(i = 1, bp = bmap + i; i < pblk; i++, bp++)
        !           281:                if(bp->type == Unk) {
        !           282:                        supererr(Efreelist, i, bp->type);
        !           283:                        return;
        !           284:                }
        !           285:        tfree = blkcnts[Free];
        !           286:        if(tfree != sblk.s_tfree)
        !           287:                supererr(Efreelist, sblk.s_tfree, tfree);
        !           288: }
        !           289: 
        !           290: chbitmap()
        !           291: {      register long *p;
        !           292:        register int i, k, j;
        !           293:        register bm *bp = bmap;
        !           294:        for(i = 0, p = (long *)freeb; i < pblk; i += 32, p++) {
        !           295:                k = *p;
        !           296:                for(j = 0; j < 32; j++, bp++) {
        !           297:                        if((k & (1 << j)) == 0)
        !           298:                                continue;
        !           299:                        if(i+j >= lblk) {
        !           300:                                supererr(Esuperfree, i+j, 0);
        !           301:                                continue;
        !           302:                        }
        !           303:                        if(bp->type == Unk) {
        !           304:                                bp->type = Free;
        !           305:                                blkcnts[Free]++;
        !           306:                        }
        !           307:                        else {
        !           308:                                supererr(Esuperfree, i+j, bp->type);
        !           309:                                return;
        !           310:                        }
        !           311:                }
        !           312:        }
        !           313:        for(i = 1, bp = bmap + i; i < pblk; i++, bp++)
        !           314:                if(bp->type == Unk) {
        !           315:                        supererr(Efreelist, i, bp->type);
        !           316:                        return;
        !           317:                }
        !           318:        tfree = blkcnts[Free];
        !           319:        if(tfree != sblk.s_tfree)
        !           320:                supererr(Efreelist, sblk.s_tfree, tfree);
        !           321: }
        !           322: 
        !           323: ch1free()
        !           324: {      int i, j, k;
        !           325:        daddr_t *p;
        !           326:        /* these could be unified if S_nfree were an int, not a short */
        !           327:        for(i = 0; i < sblk.U.R.S_nfree; i++) {
        !           328:                j = sblk.U.R.S_free[i];
        !           329:                if(j >= fblk && j < lblk && !bmap[j].ino) {
        !           330:                        if(bmap[j].type)
        !           331:                                adderr(Edup, j, 0);
        !           332:                        bmap[j].type = Free;
        !           333:                        blkcnts[Free]++;
        !           334:                }
        !           335:                else if(j)
        !           336:                        inoerr(Ebadaddr, 0, j);
        !           337:        }
        !           338:        if((j = sblk.U.R.S_free[0]) == 0)
        !           339:                return;
        !           340: loop:
        !           341:        if(bread(j, buf, 1)) {
        !           342:                pmesg("couldn't read free blk %d\n", j);
        !           343:                bmap[j].type = Ioerr;
        !           344:                exitcode = 1;
        !           345:                return;
        !           346:        }
        !           347:        k = ((struct fblk *)buf)->df_nfree;
        !           348:        for(p = ((struct fblk *)buf)->df_free, i = 0; i < k; i++) {
        !           349:                j = p[i];
        !           350:                if(j >= fblk && j < lblk && !bmap[j].ino) {
        !           351:                        if(bmap[j].type)
        !           352:                                adderr(Edup, j, 0);
        !           353:                        bmap[j].type = Free;
        !           354:                        blkcnts[Free]++;
        !           355:                }
        !           356:                else if(j)
        !           357:                        inoerr(Ebadaddr, 0, j);
        !           358:        }
        !           359:        if(j = p[0])
        !           360:                goto loop;
        !           361: }
        !           362: 
        !           363: report()
        !           364: {      int i, cnts[32], j, k;
        !           365:        for(i = 0; i < iptr; i++) {
        !           366:                j = iarg[i];
        !           367:                if(j < 1 || j >= ninode) {
        !           368:                        pmesg("arg ino %d out of range\n", j);
        !           369:                        continue;
        !           370:                }
        !           371:                pmesg("arg ino %s\n", prino(j));
        !           372:                if(imap[j].type == Dir) {
        !           373:                        for(k = 0; k < pblk; k++)
        !           374:                                if(bmap[k].ino == j && bmap[k].type == First)
        !           375:                                        pmesg(" (first blk %d)\n", k);
        !           376:                }
        !           377:        }
        !           378:        for(i = 0; i < bptr; i++) {
        !           379:                j = barg[i];
        !           380:                if(j < 0 || j > pblk) {
        !           381:                        pmesg("arg blk %d out of range\n", j);
        !           382:                        continue;
        !           383:                }
        !           384:                pmesg("arg blk %d(%s) %s\n", j, btype(bmap[j].type),
        !           385:                        prino(bmap[j].ino));
        !           386:        }
        !           387:        if(!flags['v'])
        !           388:                return;
        !           389:        pmesg("dmapptr %d erptr %d\n", dmapptr, erptr);
        !           390:        pmesg("\tinodes:\n");
        !           391:        for(i = 0; i < 32; i++)
        !           392:                cnts[i] = 0;
        !           393:        for(i = 1; i < ninode; i++)
        !           394:                cnts[imap[i].type]++;
        !           395:        for(i = 0; i < 32; i++)
        !           396:                if(cnts[i])
        !           397:                        pmesg("%s %d\n", itype(i), cnts[i]);
        !           398:        pmesg("\tblocks:\n");
        !           399:        for(i = 0; i < 32; i++)
        !           400:                if(blkcnts[i])
        !           401:                        pmesg("%s %d\n", btype(i), blkcnts[i]);
        !           402:        rpterrs();
        !           403: }

unix.superglobalmegacorp.com

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