Annotation of coherent/b/etc/fsck/phase1.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     phase 1 of fsck - Check Blocks and Sizes
                      3:  */
                      4: 
                      5: #include "fsck.h"
                      6: 
                      7: char   databuf[BSIZE];         /* buffer for blocks */
                      8: 
                      9: int    clrflg;                 /* indicates when to clear an inode */
                     10: int    dupflag;                /* indicates whether there are any dups */
                     11: 
                     12: int    numbad;                 /* number of bad blocks in the inode   */
                     13: int    numdup;                 /* number of duplicate blocks in inode */
                     14: long   numblks;                /* number of data blks for size check */
                     15: long   sparsecnt;              /* count for sparse blocks for size check */
                     16: 
                     17: /*  The following is a table of the number of direct blocks pointed at by the
                     18:  *  four types of blocks direct, ..., triple-indirect, to help count sparse
                     19:  *  blocks.
                     20:  */
                     21: 
                     22: daddr_t        blockcnt[] = {1, (daddr_t)NBN, (daddr_t)NBN*NBN, (daddr_t)NBN*NBN*NBN};
                     23: 
                     24: phase1()
                     25: {
                     26:        if (!qflag)
                     27:                printf("Phase 1 : Check Blocks and Sizes\n");
                     28:        dupflag = FALSE;
                     29:        inodescan();
                     30:        if (dupflag)
                     31:                phase1b();      
                     32: }
                     33: 
                     34: inodescan()
                     35: {
                     36:        register daddr_t bn;
                     37:        register struct dinode *dip;
                     38:        register ino_t  ino;
                     39:        int i;
                     40: 
                     41:        ino = 1;
                     42: 
                     43:        for (bn=INODEI; bn<isize; bn++) {
                     44:                if (testblock(bn)) {            /* block is bad via inode 1 */
                     45:                        ino += INOPB;
                     46:                        continue;
                     47:                }
                     48:                bread(bn, databuf);
                     49:                clrflg = FALSE;
                     50:                dip = (struct dinode *) databuf;
                     51:                for (i=0; i<INOPB; i++) {
                     52:                        candino(dip);
                     53:                        if (inuse(dip) == TRUE) {
                     54:                                if (!fflag) 
                     55:                                        checkmode(dip, ino);
                     56:                                if ( checkblks(dip, ino) != STOP ) 
                     57:                                        if ( qflag == FALSE )
                     58:                                                checksize(dip, ino);
                     59:                        }
                     60:                        candino(dip);
                     61:                        ino++;
                     62:                        dip++;
                     63:                }
                     64:                if (clrflg)
                     65:                        bwrite(bn, databuf);
                     66:        }
                     67: }
                     68: 
                     69: /*
                     70:  *     Determine if the given inode is in use.
                     71:  */
                     72: 
                     73: inuse(dip)
                     74: register struct dinode *dip;
                     75: {
                     76: #ifdef NOT_ALL_ZERO_INODE
                     77: 
                     78:        if ( (dip->di_mode != 0) || (dip->di_nlink != 0) )
                     79:                return(TRUE);
                     80:        else
                     81:                return(FALSE);
                     82: #endif
                     83: #ifdef ALL_ZERO_INODE
                     84: 
                     85:        register char *ptr;
                     86:        register struct dinode *next;
                     87: 
                     88:        ptr = (char *) dip;
                     89:        next = dip + 1;
                     90:        while (ptr < next)
                     91:                if (*ptr++ != 0)
                     92:                        return(TRUE);
                     93: 
                     94:        return(FALSE);
                     95: #endif
                     96: }
                     97: 
                     98: /*
                     99:  *     Check the mode of the given inode
                    100:  */
                    101: 
                    102: checkmode(dip, ino)
                    103: register struct dinode *dip;
                    104: register ino_t ino;
                    105: {
                    106:        register unsigned short mode;
                    107: 
                    108:        mode = dip->di_mode & IFMT;
                    109: 
                    110:        switch (mode) {
                    111:        case IFREG:
                    112:                setflags(ino, IREG);
                    113:                return;
                    114:        case IFDIR:
                    115:                setflags(ino, IDIR);
                    116:                return;
                    117:        case IFCHR:
                    118:                setflags(ino, ICHR);
                    119:                return;
                    120:        case IFBLK:
                    121:                setflags(ino, IBLK);
                    122:                return;
                    123:        case IFPIPE:
                    124:                setflags(ino, IPIPE);
                    125:                return;
                    126:        default:
                    127:                setflags(ino, UNKNOWN);
                    128:                break;
                    129:        }
                    130: 
                    131:        switch ( query("Unknown File Type i-number = %u (Clear)", ino) ){
                    132:        case NO:
                    133:                return;
                    134:        case YES:
                    135:                zeroinode(dip);
                    136:                setflags(ino, UNALLOC);
                    137:                clrflg = TRUE;
                    138:                break;
                    139:        }
                    140: }
                    141: 
                    142: /*
                    143:  *     Zero the given inode
                    144:  */
                    145: 
                    146: zeroinode(dip)
                    147: struct dinode *dip;
                    148: {
                    149:        register char *ptr;
                    150:        register struct dinode *next;
                    151: 
                    152:        lostsize += dip->di_size;
                    153:        next = dip+1;
                    154:        ptr = (char *) dip;
                    155: 
                    156:        while (ptr < next)
                    157:                *ptr++ = 0;
                    158: 
                    159: }
                    160: 
                    161: /*
                    162:  *     Check the blocks associated with the given inode to determine
                    163:  *     if any are bad or duplicate
                    164:  */
                    165: 
                    166: checkblks(dip, ino)
                    167: struct dinode *dip;
                    168: ino_t  ino;
                    169: {
                    170:        daddr_t addrs[NADDR];
                    171:        register daddr_t bn;
                    172:        register int i, lev, naddr;
                    173:        register int mode;
                    174: 
                    175:        mode = dip->di_mode & IFMT;
                    176: 
                    177:        if ( (mode == IFREG) || (mode == IFDIR) )
                    178:                l3tol(addrs, dip->di_addr, naddr=NADDR);
                    179:        else if ( mode == IFPIPE )
                    180:                l3tol(addrs, dip->di_addp, naddr=ND);
                    181:        else
                    182:                return(STOP);
                    183: 
                    184:        numbad =                        /* number of bad blocks so far */
                    185:        numdup =                        /* num dup blocks so far THIS INODE */
                    186:        numblks =                       /* num used data blocks for size chk */
                    187:        sparsecnt = 0;                  /* count of missed data blocks  */
                    188: 
                    189:        for(i=0; i<naddr; i++)
                    190:                for (lev=0; lev<4; lev++) 
                    191:                        if (i < offsets[lev]) {
                    192:                                if ( (bn=addrs[i]) != 0 ) {
                    193:                                        if (doblocks(bn, ino, lev) == STOP)
                    194:                                                return(STOP);
                    195:                                } else
                    196:                                        sparsecnt += blockcnt[lev];
                    197:                                break;
                    198:                        }
                    199:        return(OK);
                    200: }
                    201: 
                    202: /*
                    203:  *     Checks recursively the blocks pointed at via
                    204:  *     the inode list of blocks.  'bn' is the block number,
                    205:  *     'ino' is the inode referencing it, and 'lev' is the
                    206:  *     level 0 == direct ... 3 = triple-indirect
                    207:  */
                    208: 
                    209: doblocks(bn, ino, lev)
                    210: register daddr_t bn;
                    211: ino_t  ino;
                    212: int    lev;
                    213: {
                    214:        char buf[BSIZE];
                    215:        register daddr_t *bnptr;
                    216:        register char *end;
                    217:        register int flag;
                    218: 
                    219:        if (lev-- == 0) {               /* we have a direct block */
                    220:                numblks += sparsecnt + 1;
                    221:                sparsecnt = 0;
                    222:                return(dodirect(bn, ino));
                    223:        } else {
                    224:                end = &buf[BSIZE];
                    225:                if ( (flag=dodirect(bn, ino)) == OK ) {
                    226:                        bread(bn, buf);
                    227:                        bnptr = (long *) buf;
                    228:                        while ( bnptr < end ) {
                    229:                                bn = *bnptr++;
                    230:                                candaddr(bn);
                    231:                                if ( bn == 0 ) {
                    232:                                        sparsecnt += blockcnt[lev];
                    233:                                        continue;
                    234:                                }
                    235:                                if ( doblocks(bn, ino, lev) == STOP )
                    236:                                        return(STOP);
                    237:                        }
                    238:                        return(OK);
                    239:                } else 
                    240:                        return(flag);
                    241:        }
                    242: }
                    243:                        
                    244: /*
                    245:  *     Check the given block to determine if it is bad
                    246:  *     or if it is a duplicate.  'ino' is the inode referencing it
                    247:  */
                    248: 
                    249: dodirect(bn, ino)
                    250: register daddr_t bn;
                    251: register ino_t ino;
                    252: {
                    253:        register int flag;
                    254:        
                    255:        if ( (flag=checkbad(bn, ino)) == OK ) 
                    256:                return( checkdup(bn, ino) );
                    257:        else
                    258:                return(flag);
                    259: }
                    260: 
                    261: /*
                    262:  *     Check the given block number for being bad.
                    263:  */
                    264: 
                    265: checkbad(bn, ino)
                    266: register daddr_t bn;
                    267: ino_t  ino;
                    268: {
                    269:        if ( (bn>=isize) && (bn<fsize) )
                    270:                return(OK);
                    271: 
                    272:        else if ( (bn<isize) && (bn>=INODEI) && (ino == 1) ) {
                    273:                                                        /* bad block is in  */
                    274:                totfree++;                              /* the inode blocks */
                    275:                return(OK);
                    276:        }
                    277:                
                    278:        if (!fflag)
                    279:                orflags(ino, IBAD_IDUP);
                    280: 
                    281:        printf("Bad block %lu, i-number = %u\n", bn, ino);
                    282: 
                    283:        if (numbad++ < MAXBADOK)
                    284:                return(BAD_DUP);
                    285: 
                    286:        switch ( query("Excessive Bad Blocks i-number = %u (Continue)", ino) ){
                    287:        case NO:
                    288:                abort();
                    289:        case YES:
                    290:                return(STOP);
                    291:        }
                    292: }
                    293: 
                    294: 
                    295: /*
                    296:  *     Check the given block number for duplicate reference.
                    297:  */
                    298: 
                    299: checkdup(bn, ino)
                    300: register daddr_t bn;
                    301: ino_t  ino;
                    302: {
                    303:        if ( !testblock(bn) ) {
                    304:                markblock(bn);
                    305:                totfree--;
                    306:                return(OK);
                    307:        }
                    308: 
                    309:        dupflag = TRUE;
                    310:        if (!fflag)
                    311:                orflags(ino, IBAD_IDUP);
                    312:        printf("Dup Block %lu, i-number = %u\n", bn, ino);
                    313: 
                    314:        if (totdups < DUPTBLSIZE) 
                    315:                dupblck[totdups++] = bn;
                    316:        else {
                    317:                switch ( query("DUP Table Overflow (Continue)") ) {
                    318:                case NO:
                    319:                        abort();
                    320:                case YES:
                    321:                        return(BAD_DUP);
                    322:                }
                    323:        }
                    324: 
                    325:        if (numdup++ < MAXDUPOK)
                    326:                return(BAD_DUP);
                    327: 
                    328:        switch ( query("Excessive Dup Blocks i-number = %u (Continue)", ino) ) {
                    329:        case NO:
                    330:                abort();
                    331:        case YES:
                    332:                return(STOP);
                    333:        }
                    334: }
                    335: 
                    336: /*
                    337:  *     Check For Possible File Size Error 
                    338:  */
                    339: 
                    340: checksize(dip, ino)
                    341: register struct dinode *dip;
                    342: ino_t  ino;
                    343: {
                    344:        register int mode;
                    345:        register fsize_t size;
                    346: 
                    347:        mode = dip->di_mode & IFMT;
                    348:        size = dip->di_size;
                    349:        
                    350:        if ( mode == IFREG )
                    351:                filesize(ino, size);
                    352:        else if ( mode == IFDIR )
                    353:                dirsize(dip, ino, size);
                    354:        else if ( mode == IFPIPE )
                    355:                pipesize(dip, ino, size);
                    356: }
                    357: 
                    358: dirsize(dip, ino, size)
                    359: struct dinode *dip;
                    360: ino_t ino;
                    361: register fsize_t size;
                    362: {
                    363:        if ( size <= 0 ) {
                    364:                switch ( query("\
                    365: Bad Directory Size, size = %D, i-number = %u (Clear i-node)", size, ino) ) {
                    366:                case NO:
                    367:                        break;
                    368:                case YES:
                    369:                        zeroinode(dip);
                    370:                        setflags(ino, UNALLOC);
                    371:                        clrflg = TRUE;
                    372:                        return;
                    373:                }
                    374:        }
                    375: 
                    376:        if ( size < (2*DSIZE) )
                    377:                printf("Directory Size too small i-number = %u\n", ino);
                    378: 
                    379:        if ( size % sizeof(struct direct) != 0 )
                    380:                printf("Directory Misaligned i-number = %u\n", ino);
                    381: 
                    382:        if (sizerr(size))
                    383:                printf("Possible Directory Size Error i-number = %u\n", ino);
                    384: }
                    385: 
                    386: filesize(ino, size)
                    387: ino_t ino;
                    388: register fsize_t size;
                    389: {
                    390:        if (sizerr(size))
                    391:                printf("Possible File Size Error i-number = %u\n", ino);
                    392: }
                    393: 
                    394: pipesize(dip, ino, size)
                    395: struct dinode *dip;
                    396: ino_t ino;
                    397: register fsize_t size;
                    398: {
                    399:        if (sizerr(size))
                    400:                printf("Possible PIPE Size Error i-number = %u\n", ino);
                    401:        return;
                    402: }
                    403: 
                    404: sizerr(size)
                    405: register fsize_t size;
                    406: {
                    407:        register fsize_t calc;
                    408: 
                    409:        calc = (unsigned long)numblks*BSIZE;
                    410:        if ( (size > calc) || ( calc >= (size+BSIZE) ) ) 
                    411:                return(TRUE);
                    412:        else
                    413:                return(FALSE);
                    414: }

unix.superglobalmegacorp.com

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