Annotation of coherent/d/etc/fsck/phase1.c, revision 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;
        !           173:        register int mode;
        !           174: 
        !           175:        mode = dip->di_mode & IFMT;
        !           176: 
        !           177:        if ( (mode != IFREG) && (mode != IFDIR) )
        !           178:                return(STOP);
        !           179: 
        !           180:        l3tol(addrs, dip->di_addr, NADDR);
        !           181: 
        !           182:        numbad =                        /* number of bad blocks so far */
        !           183:        numdup =                        /* num dup blocks so far THIS INODE */
        !           184:        numblks =                       /* num used data blocks for size chk */
        !           185:        sparsecnt = 0;                  /* count of missed data blocks  */
        !           186: 
        !           187:        for(i=0; i<NADDR; i++)
        !           188:                for (lev=0; lev<4; lev++) 
        !           189:                        if (i < offsets[lev]) {
        !           190:                                if ( (bn=addrs[i]) != 0 ) {
        !           191:                                        if (doblocks(bn, ino, lev) != OK)
        !           192:                                                return(STOP);
        !           193:                                } else
        !           194:                                        sparsecnt += blockcnt[lev];
        !           195:                                break;
        !           196:                        }
        !           197:        return(OK);
        !           198: }
        !           199: 
        !           200: /*
        !           201:  *     Checks recursively the blocks pointed at via
        !           202:  *     the inode list of blocks.  'bn' is the block number,
        !           203:  *     'ino' is the inode referencing it, and 'lev' is the
        !           204:  *     level 0 == direct ... 3 = triple-indirect
        !           205:  */
        !           206: 
        !           207: doblocks(bn, ino, lev)
        !           208: register daddr_t bn;
        !           209: ino_t  ino;
        !           210: int    lev;
        !           211: {
        !           212:        char buf[BSIZE];
        !           213:        register daddr_t *bnptr;
        !           214:        register char *end;
        !           215:        register int flag;
        !           216: 
        !           217:        if (lev-- == 0) {               /* we have a direct block */
        !           218:                numblks += sparsecnt + 1;
        !           219:                sparsecnt = 0;
        !           220:                return(dodirect(bn, ino));
        !           221:        } else {
        !           222:                end = &buf[BSIZE];
        !           223:                if ( (flag=dodirect(bn, ino)) == OK ) {
        !           224:                        bread(bn, buf);
        !           225:                        bnptr = (long *) buf;
        !           226:                        while ( bnptr < end ) {
        !           227:                                bn = *bnptr++;
        !           228:                                candaddr(bn);
        !           229:                                if ( bn == 0 ) {
        !           230:                                        sparsecnt += blockcnt[lev];
        !           231:                                        continue;
        !           232:                                }
        !           233:                                if ( doblocks(bn, ino, lev) == STOP )
        !           234:                                        return(STOP);
        !           235:                        }
        !           236:                        return(OK);
        !           237:                } else 
        !           238:                        return(flag);
        !           239:        }
        !           240: }
        !           241:                        
        !           242: /*
        !           243:  *     Check the given block to determine if it is bad
        !           244:  *     or if it is a duplicate.  'ino' is the inode referencing it
        !           245:  */
        !           246: 
        !           247: dodirect(bn, ino)
        !           248: register daddr_t bn;
        !           249: register ino_t ino;
        !           250: {
        !           251:        register int flag;
        !           252:        
        !           253:        if ( (flag=checkbad(bn, ino)) == OK ) 
        !           254:                return( checkdup(bn, ino) );
        !           255:        else
        !           256:                return(flag);
        !           257: }
        !           258: 
        !           259: /*
        !           260:  *     Check the given block number for being bad.
        !           261:  */
        !           262: 
        !           263: checkbad(bn, ino)
        !           264: register daddr_t bn;
        !           265: ino_t  ino;
        !           266: {
        !           267:        if ( (bn>=isize) && (bn<fsize) )
        !           268:                return(OK);
        !           269: 
        !           270:        else if ( (bn<isize) && (bn>=INODEI) && (ino == 1) ) {
        !           271:                                                        /* bad block is in  */
        !           272:                totfree++;                              /* the inode blocks */
        !           273:                return(OK);
        !           274:        }
        !           275:                
        !           276:        if (!fflag)
        !           277:                orflags(ino, IBAD_IDUP);
        !           278: 
        !           279:        printf("Bad block %U, i-number = %u\n", bn, ino);
        !           280: 
        !           281:        if (numbad++ < MAXBADOK)
        !           282:                return(BAD_DUP);
        !           283: 
        !           284:        switch ( query("Excessive Bad Blocks i-number = %u (Continue)", ino) ){
        !           285:        case NO:
        !           286:                abort();
        !           287:        case YES:
        !           288:                return(STOP);
        !           289:        }
        !           290: }
        !           291: 
        !           292: 
        !           293: /*
        !           294:  *     Check the given block number for duplicate reference.
        !           295:  */
        !           296: 
        !           297: checkdup(bn, ino)
        !           298: register daddr_t bn;
        !           299: ino_t  ino;
        !           300: {
        !           301:        if ( !testblock(bn) ) {
        !           302:                markblock(bn);
        !           303:                totfree--;
        !           304:                return(OK);
        !           305:        }
        !           306: 
        !           307:        dupflag = TRUE;
        !           308:        if (!fflag)
        !           309:                orflags(ino, IBAD_IDUP);
        !           310:        printf("Dup Block %U, i-number = %u\n", bn, ino);
        !           311: 
        !           312:        if (totdups < DUPTBLSIZE) 
        !           313:                dupblck[totdups++] = bn;
        !           314:        else {
        !           315:                switch ( query("DUP Table Overflow (Continue)") ) {
        !           316:                case NO:
        !           317:                        abort();
        !           318:                case YES:
        !           319:                        return(BAD_DUP);
        !           320:                }
        !           321:        }
        !           322: 
        !           323:        if (numdup++ < MAXDUPOK)
        !           324:                return(BAD_DUP);
        !           325: 
        !           326:        switch ( query("Excessive Dup Blocks i-number = %u (Continue)", ino) ) {
        !           327:        case NO:
        !           328:                abort();
        !           329:        case YES:
        !           330:                return(STOP);
        !           331:        }
        !           332: }
        !           333: 
        !           334: /*
        !           335:  *     Check For Possible File Size Error 
        !           336:  */
        !           337: 
        !           338: checksize(dip, ino)
        !           339: register struct dinode *dip;
        !           340: ino_t  ino;
        !           341: {
        !           342:        register int mode;
        !           343:        register fsize_t size;
        !           344: 
        !           345:        mode = dip->di_mode & IFMT;
        !           346:        size = dip->di_size;
        !           347:        
        !           348:        if ( mode == IFREG )
        !           349:                filesize(ino, size);
        !           350:        else    /* mode == IFDIR */
        !           351:                dirsize(dip, ino, size);
        !           352: }
        !           353: 
        !           354: dirsize(dip, ino, size)
        !           355: struct dinode *dip;
        !           356: ino_t ino;
        !           357: register fsize_t size;
        !           358: {
        !           359:        if ( size <= 0 ) {
        !           360:                switch ( query("\
        !           361: Bad Directory Size, size = %D, i-number = %u (Clear i-node)", size, ino) ) {
        !           362:                case NO:
        !           363:                        break;
        !           364:                case YES:
        !           365:                        zeroinode(dip);
        !           366:                        setflags(ino, UNALLOC);
        !           367:                        clrflg = TRUE;
        !           368:                        return;
        !           369:                }
        !           370:        }
        !           371: 
        !           372:        if ( size < (2*DSIZE) )
        !           373:                printf("Directory Size too small i-number = %u\n", ino);
        !           374: 
        !           375:        if ( size % sizeof(struct direct) != 0 )
        !           376:                printf("Directory Misaligned i-number = %u\n", ino);
        !           377: 
        !           378:        if (sizerr(size))
        !           379:                printf("Possible Directory Size Error i-number = %u\n", ino);
        !           380: }
        !           381: 
        !           382: filesize(ino, size)
        !           383: ino_t ino;
        !           384: register fsize_t size;
        !           385: {
        !           386:        if (sizerr(size))
        !           387:                printf("Possible File Size Error i-number = %u\n", ino);
        !           388: }
        !           389: 
        !           390: sizerr(size)
        !           391: register fsize_t size;
        !           392: {
        !           393:        register fsize_t calc;
        !           394: 
        !           395:        calc = (unsigned long)numblks*BSIZE;
        !           396:        if ( (size > calc) || ( calc >= (size+BSIZE) ) ) 
        !           397:                return(TRUE);
        !           398:        else
        !           399:                return(FALSE);
        !           400: }

unix.superglobalmegacorp.com

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