Annotation of researchv10no/cmd/chuck/check.c, revision 1.1.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.