Annotation of coherent/b/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, 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.