Annotation of coherent/d/etc/fsck/phase4.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     phase 4 of fsck - Check Reference Counts
                      3:  */
                      4: 
                      5: #include "fsck.h"
                      6: 
                      7: extern char *reconnect;
                      8: fsize_t        lostsize;
                      9: 
                     10: phase4()
                     11: {
                     12:        ino_t i;
                     13:        short actlink;
                     14: 
                     15:        if (!qflag)
                     16:                printf("Phase 4 : Check Reference Counts\n");
                     17:        for (i=FIRSTIN; i<=ninodes; i++) {
                     18:                if ( badblks(i) )
                     19:                        if ( bddp(i) == YES )
                     20:                                continue;       /* inode zeroed */
                     21: 
                     22:                if ( (linkctr(i) == 0) &&
                     23:                     ((flags(i)&MODEMASK) != IDIR) &&
                     24:                     ((flags(i)&ALLOCMASK) != UNALLOC) )
                     25:                        if ( unreflink(i) == YES )
                     26:                                continue;       /* inode zeroed */
                     27: 
                     28:                if ( (linkctr(i) == 0) &&
                     29:                     ((flags(i)&ALLOCMASK) != UNALLOC)  )
                     30:                        if ( unrefclr(i) == YES )
                     31:                                continue;       /* inode zeroed */
                     32: 
                     33:                if ( (actlink=getlink(i)) == (-1) ) {
                     34:                        i += INOPB-1;
                     35:                        continue;               /* bad inode block */
                     36:                }
                     37: 
                     38:                if ( actlink != linkctr(i) )
                     39:                        linkprob(i, actlink);   /* fix link count */
                     40:        }
                     41: 
                     42:        freeilist();
                     43: }
                     44: 
                     45: short
                     46: getlink(inum)
                     47: register ino_t inum;
                     48: {
                     49:        register unsigned offset;
                     50:        static ibuf[BSIZE];
                     51:        register struct dinode *dip;
                     52:        register daddr_t bn;
                     53: 
                     54:        offset = iblocko(inum);
                     55:        if ( (offset==0) || (inum==FIRSTIN) ) {
                     56:                bn = iblockn(inum);
                     57:                if ( (testblock(bn)) && (inum!=FIRSTIN) ) 
                     58:                        return(-1);
                     59:                bread(bn, ibuf);
                     60:        }
                     61:        dip = ((struct dinode *) ibuf) + offset;
                     62:        candino(dip);
                     63:        return(dip->di_nlink);
                     64: }
                     65: 
                     66: char *clearit = "(Clear i-node)";
                     67: 
                     68: unreflink(ino)
                     69: ino_t ino;
                     70: {
                     71:        fsize_t size;
                     72: 
                     73:        if ( (qflag == TRUE) && ((flags(ino)&MODEMASK) == IPIPE) ) {
                     74:                doclear(ino);
                     75:                return(YES);
                     76:        }
                     77: 
                     78:        printf("Unref %s\n", typename(ino));
                     79:        size = pinfo(ino);
                     80:        if ( (daction != NO) && (size == 0) && (mounted == FALSE) 
                     81:                && ((flags(ino)&MODEMASK) == IREG) ) {
                     82:                printf("%s [Forced - Yes]\n", clearit);
                     83:                doclear(ino);
                     84:                return(YES);
                     85:        }
                     86:        if ( action(reconnect) == TRUE )
                     87:                if( connect(ino, IREG) == FAILURE )  /* connect back in the */
                     88:                        return(askclear(ino));       /* non dir inode       */
                     89:                        
                     90:        return(NO);
                     91: }
                     92: 
                     93: askclear(ino)
                     94: ino_t ino;
                     95: {
                     96:        if ( action(clearit) == TRUE ) {
                     97:                doclear(ino);
                     98:                return(YES);
                     99:        }
                    100:        return(NO);
                    101: }
                    102: 
                    103: doclear(ino)
                    104: ino_t ino;
                    105: {
                    106:        struct dinode *dip;
                    107: 
                    108:        dip = ptrino(ino, databuf);
                    109:        zeroinode(dip);
                    110:        writeino(ino, databuf);
                    111:        setflags(ino, UNALLOC);
                    112:        setlinkctr(ino, 0);
                    113: }
                    114: 
                    115: char *adjust = "(Adjust)";
                    116: 
                    117: linkprob(ino, actlink)
                    118: ino_t ino;
                    119: short actlink;
                    120: {
                    121:        printf("Link Count discrepancy in %s\n", typename(ino));
                    122:        pinfo(ino);
                    123:        printf("Count = %u, should be %u ", actlink, linkctr(ino));
                    124:        if ( action(adjust) == TRUE )
                    125:                chglink(ino);
                    126: }
                    127: 
                    128: chglink(ino)
                    129: ino_t ino;
                    130: {
                    131:        struct dinode *dip;
                    132: 
                    133:        dip = ptrino(ino, databuf);
                    134:        dip->di_nlink = linkctr(ino);
                    135:        writeino(ino, databuf);
                    136: }
                    137:        
                    138: unrefclr(ino)
                    139: ino_t ino;
                    140: {
                    141:        printf("Unref %s\n", typename(ino));
                    142:        pinfo(ino);
                    143:        return(askclear(ino));
                    144: }
                    145: 
                    146: bddp(ino)
                    147: ino_t ino;
                    148: {
                    149:        printf("Bad/Dup blocks in %s\n", typename(ino));
                    150:        pinfo(ino);
                    151:        return(askclear(ino));
                    152: }
                    153: 
                    154: char *fixit = "(FIX)";
                    155: 
                    156: freeilist()
                    157: {
                    158:        ino_t i, count=0;
                    159:        daddr_t bn;
                    160: 
                    161:        for (i=FIRSTIN; i<=ninodes; i++)
                    162:                if ( (flags(i)&ALLOCMASK) == UNALLOC )
                    163:                        count++;
                    164: 
                    165:        for (bn=INODEI+1; bn<isize; bn++)       /* block # INODEI can't */
                    166:                if ( testblock(bn) )            /* be bad since ROOTIN  */
                    167:                        count -= INOPB;         /* is in it, otherwise  */
                    168:                                                /* big time bad news.   */
                    169:        if ( sbp->s_tinode != count ) 
                    170:                if ( (qflag==FALSE) && (daction!=NO) ) {
                    171:                        printf("Free i-node count wrong in superblock.  ");
                    172:                        if ( action(fixit) == TRUE ) {
                    173:                                sbp->s_tinode = count;
                    174:                                sbpfix = TRUE;
                    175:                        }
                    176:                } else {
                    177:                        sbp->s_tinode = count;
                    178:                        sbpfix = TRUE;
                    179:                }
                    180: 
                    181:        if ( (daction!=NO) &&
                    182:             ( (sflag==TRUE) || (sbpfix==TRUE) || (badilist()==BAD) ) )
                    183:                rebuild();
                    184: 
                    185: }
                    186: 
                    187: badilist()
                    188: {
                    189:        ino_t i, inum;
                    190:        unsigned numfree;
                    191:        daddr_t bn;
                    192: 
                    193:        if ( (numfree=(unsigned) sbp->s_ninode) > NICINOD )
                    194:                return(BAD);
                    195:        for (i=0; i<numfree; i++) {
                    196:                inum = sbp->s_inode[i];
                    197:                if ( (inum < FIRSTIN) || (inum > ninodes) )
                    198:                        return(BAD);
                    199:                bn = iblockn(inum);
                    200:                if ( (testblock(bn)) && (bn!=INODEI) )
                    201:                        return(BAD);
                    202:                if ( (flags(inum)&ALLOCMASK) != UNALLOC ) 
                    203:                        return(BAD);
                    204:                if ( flags(inum)&IFREELIST )
                    205:                        return(BAD);            /* dup in ifree list */
                    206:                orflags(inum, IFREELIST);
                    207:        }
                    208:        return(GOOD);
                    209: }
                    210: 
                    211: rebuild()
                    212: {
                    213:        daddr_t bn;
                    214:        ino_t i;
                    215:        int index;
                    216: 
                    217:        sbpfix = TRUE;
                    218:        for (i=FIRSTIN, index=0; (i<=ninodes) && (index<NICINOD); i++) {
                    219:                if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
                    220:                        bn = iblockn(i);
                    221:                        if ( (!testblock(bn)) || (bn==INODEI) )
                    222:                                index++;
                    223:                }
                    224:        }
                    225:        sbp->s_ninode = index;
                    226:        for (i=FIRSTIN; (i<=ninodes) && (index>0); i++) {
                    227:                if ( (flags(i)&ALLOCMASK) == UNALLOC ) {
                    228:                        bn = iblockn(i);
                    229:                        if ( (!testblock(bn)) || (bn==INODEI) )
                    230:                                sbp->s_inode[--index] = i;
                    231:                }
                    232:        }
                    233:        printf("Free i-node list in superblock rebuilt.\n");
                    234: }

unix.superglobalmegacorp.com

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