Annotation of researchv10no/cmd/chuck/repairs.c, revision 1.1.1.1

1.1       root        1: #include "fs.h"
                      2: 
                      3: repairs()
                      4: {      int i, j, k;
                      5:        if(erptr <= 0) {
                      6:                pmesg("all ok\n");
                      7:                return;
                      8:        }
                      9:        i = errcnts[Einvalid] + errcnts[Esuperino] + errcnts[Esuperfree]
                     10:                + errcnts[Efreelist];
                     11:        if(!flags['i'] && i == erptr) {
                     12:                pmesg("fixing super block\n");
                     13:                fixfree();
                     14:                if(!flags['w'])
                     15:                        return;
                     16:                if(bwrite(1, (char *)&sblk, 1))
                     17:                        fatal("write failed\n");
                     18:                pmesg("done\n");
                     19:                return;
                     20:        }
                     21:        if(!flags['i'] && i + errcnts[Enullable] == erptr) {
                     22:                pmesg("clearing %d inodes safely\n", errcnts[Enullable]);
                     23:                /* even if it is a directory.  no links means Edot, Edotdot... */
                     24:                for(j = 0; j < erptr; j++)
                     25:                        if(erlist[j].type == Enullable)
                     26:                                clri(erlist[j].a);
                     27:                fixfree();
                     28:                return;
                     29:        }
                     30:        /* now we enter upon the realm of the speculative */
                     31:        if(!flags['i'] && !errcnts[Edup]) {
                     32:                pmesg("hi ho hi ho, it's off to work we go\n");
                     33:                if(j = errcnts[Enullable])
                     34:                        pmesg("clearing %d inodes safely\n", j);
                     35:                for(j = 0; j < erptr; j++)
                     36:                switch(erlist[j].done? 0: erlist[j].type) {
                     37:                case 0:
                     38:                        continue;
                     39:                default:
                     40:                        pmesg("%s %d %d, not handled\n", errnm(erlist[j].type),
                     41:                                erlist[j].a, erlist[j].b);
                     42:                        exitcode++;
                     43:                        continue;
                     44:                case Ehole:
                     45:                        pmesg("%s ends with a hole, remove or copy\n", prino(erlist[j].a));
                     46:                        continue;
                     47:                case Enullable:
                     48:                        clri(erlist[j].a);
                     49:                        erlist[j].done = 1;
                     50:                        continue;
                     51:                case Enotdot: case Enotdotdot: case Edotino: case Ebadparent:
                     52:                        k = erlist[j].a;
                     53:                        if(k > ROOTINO)
                     54:                                fixdots(k);
                     55:                        continue;
                     56:                case Elinkcnt:
                     57:                        k = erlist[j].a;
                     58:                        if(imap[k].type == Weird) {
                     59:                                if(fixweird(k))
                     60:                                        continue;
                     61:                                pmesg("weird ino %d (strange type): fix manually\n", k);
                     62:                                exitcode = 1;
                     63:                                continue;
                     64:                        }
                     65:                        if(imap[k].nrefs == 0)
                     66:                                attach(k);
                     67:                        else if(imap[k].type != Unalloc)
                     68:                                fixlinks(erlist[j].a);
                     69:                        else if(imap[k].nrefs == 1)
                     70:                                expunge(k);
                     71:                        else {
                     72:                                pmesg("%s has %d references!  Expunging.\n", prino(k),
                     73:                                        imap[k].nrefs);
                     74:                                expunge(k);
                     75:                                exitcode = 1;   /* things are not ok */
                     76:                                continue;
                     77:                        }
                     78:                        erlist[j].done = 1;
                     79:                        continue;
                     80:                case Ebadname:
                     81:                        pmesg("%s has a weird name, look at it\n", prino(erlist[j].b));
                     82:                        fixnames(erlist[j].a);
                     83:                        continue;
                     84:                case Ebadino:   /* these are lost files */
                     85:                        pmesg("removing bad inos from %s\n", prino(erlist[j].a));
                     86:                        fixnames(erlist[j].a);
                     87:                        continue;
                     88:                case Einvalid: case Efreelist: case Esuperino:
                     89:                        continue;       /* fixfree() comes later */
                     90:                case Eattach:
                     91:                        attach(erlist[j].a);
                     92:                        erlist[j].done = 1;
                     93:                        continue;
                     94:                case Efakeroot:
                     95:                        attach(erlist[j].a);
                     96:                        fixdots(erlist[j].a);
                     97:                        continue;
                     98:                }
                     99:                fixfree();
                    100:                return;
                    101:        }
                    102:        rpterrs();
                    103:        if(flags['i'])
                    104:                interact();
                    105:        else
                    106:                exitcode = 1;
                    107: }
                    108: 
                    109: rpterrs()
                    110: {      int i, j, k, cnts[32];
                    111:        struct dinode *dp;
                    112:        if(erptr > 30 && !flags['v']) {
                    113:                pmesg("%d errors\n", erptr);
                    114:                for(i = 0; i < 32; i++)
                    115:                        cnts[i] = 0;
                    116:                for(i = 0; i < erptr; i++)
                    117:                        cnts[erlist[i].type]++;
                    118:                for(i = 0; i < 32; i++)
                    119:                        if(cnts[i])
                    120:                                pmesg("%s\t%d\n", errnm(i), cnts[i]);
                    121:                return;
                    122:        }
                    123:        for(i = 0; i < erptr; i++)
                    124:                switch(erlist[i].type) {
                    125:                default:
                    126:                        pmesg("%s %d %d\n", errnm(erlist[i].type),
                    127:                                erlist[i].a, erlist[i].b);
                    128:                        continue;
                    129:                case Efakeroot:
                    130:                        pmesg("own parent %s\n", prino(erlist[i].a));
                    131:                        continue;
                    132:                case Edup:
                    133:                        j = erlist[i].b;
                    134:                        k = bmap[erlist[i].a].ino;
                    135:                        pmesg("dup block %d %s %s\n", erlist[i].a, prino(j), prino(k));
                    136:                        continue;
                    137:                case Elinkcnt:
                    138:                        j = erlist[i].a;
                    139:                        dp = (struct dinode *)(buf + 2*bsize + (j-1)*sizeof(*dp));
                    140:                        pmesg("Elinkcnt(%s) refs %d(parent %s)\n", prino(j), imap[j].nrefs,
                    141:                                prino(imap[j].parent));
                    142:                        continue;
                    143:                case Ebadparent:
                    144:                        j = erlist[i].a;
                    145:                        k = erlist[i].b;
                    146:                        pmesg("Ebadparent: (%s) not in (%s)\n", prino(j), prino(k));
                    147:                        continue;
                    148:                case Ebadname:
                    149:                        j = erlist[i].a;
                    150:                        k = erlist[i].b;
                    151:                        pmesg("Ebadname (%s) (in %s)\n", prino(j), prino(k));
                    152:                        continue;
                    153:                }
                    154: }
                    155: 
                    156: fixfree()
                    157: {      int i, j, *p;
                    158:        sblk.s_ninode = sblk.s_tfree = 0;
                    159:        sblk.s_tinode = tinode;
                    160:        for(i = 2, j = 0; i < ninode && j < NICINOD; i++)
                    161:                if(imap[i].type == Unalloc) {
                    162:                        sblk.s_inode[j++] = i;
                    163:                        sblk.s_ninode++;
                    164:                }
                    165:        sblk.s_lasti = sblk.s_inode[0];
                    166:        sblk.s_nbehind = 0;
                    167:        if(bsize < 4096) {      /* stupid test, FIX */
                    168:                fix1free();
                    169:                return;
                    170:        }
                    171:        if(pblk > lblk) {
                    172:                for(i = 0; i < BITMAP; i++)
                    173:                        sblk.U.B.S_bfree[i] = 0;
                    174:                memset(freeb, 0, (pblk-lblk)*bsize);
                    175:                for(j = i = 0, p = (long *) freeb; i < pblk; i++, j++) {
                    176:                        if(j >= 32) {
                    177:                                j = 0;
                    178:                                p++;
                    179:                        }
                    180:                        if(bmap[i].type == Free || bmap[i].type == Unk) {
                    181:                                sblk.s_tfree++;
                    182:                                *p |= (1 << j);
                    183:                        }
                    184:                }
                    185:                if(bwrite(lblk, freeb, pblk-lblk)) {
                    186:                        exitcode = 1;
                    187:                        pmesg("bit map block write failed\n");
                    188:                }
                    189:        }
                    190:        else {
                    191:                for(i = 0, p = sblk.U.B.S_bfree; i < BITMAP; i++)
                    192:                        *p++ = 0;
                    193:                for(i = fblk, j = 0, p = sblk.U.B.S_bfree; i < pblk; i++, j++) {
                    194:                        if(j >= 32) {
                    195:                                j = 0;
                    196:                                p++;
                    197:                        }
                    198:                        if(bmap[i].type == Free || bmap[i].type == Unk) {
                    199:                                sblk.s_tfree++;
                    200:                                *p |= (1 << j);
                    201:                        }
                    202:                }
                    203:        }
                    204:        sblk.U.B.S_valid = 1;
                    205:        if(!flags['w'])
                    206:                return;
                    207:        if(bwrite(1, (char *)&sblk, 1))
                    208:                fatal("super block write failed\n");
                    209: }
                    210: 
                    211: fix1free()
                    212: {      /* fix this someday FIX */
                    213:        pmesg("get fsck to fix the free list!\n");
                    214:        if(!flags['w'])
                    215:                return;
                    216:        if(bwrite(1, (char *)&sblk, 1))
                    217:                fatal("super block write failed\n");
                    218: }
                    219: 
                    220: fixweird(n)
                    221: {      struct dinode *dp;
                    222:        dp = (struct dinode *) (buf + (n-1)*sizeof(*dp) + 2*bsize);
                    223:        if(dp->di_mode)
                    224:                return(0);
                    225:        if(dp->di_size > 0)
                    226:                return(0);
                    227:        if(imap[n].nrefs > 1)
                    228:                return(0);
                    229:        pmesg("removing weird ino %s\n", prino(n));
                    230:        if(imap[n].nrefs == 1)
                    231:                expunge(n);
                    232:        else {
                    233:                clri(n);
                    234:                pmesg("and rerun chuck\n");
                    235:        }
                    236:        return(1);
                    237: }
                    238:        
                    239: fixlinks(n)
                    240: {      struct dinode *dp;
                    241:        dp = (struct dinode *) (buf + (n-1)*sizeof(*dp) + 2*bsize);
                    242:        if(imap[n].type == Unalloc) {
                    243:                pmesg("ino %d unallocated, link count unadjusted\n", n);
                    244:                return;
                    245:        }
                    246:        pmesg("%s getting %d as links\n", prino(n), imap[n].nrefs);
                    247:        dp->di_nlink = imap[n].nrefs;
                    248:        if(flags['w'])
                    249:                wrti(n);
                    250: }
                    251: 
                    252: wrti(n)        /* write the block of inodes containing inode n */
                    253: {      int i;
                    254:        i = (n-1)/inopb + 2;
                    255:        if(bwrite(i, buf + i*bsize, 1))
                    256:                pmesg("write of block containing ino %d failed\n", n);
                    257: }
                    258: 
                    259: clri(n)
                    260: {      struct dinode *dp;
                    261:        static struct dinode nild;
                    262:        dp = (struct dinode *) (buf + (n-1)*sizeof(*dp) + 2*bsize);
                    263:        switch(imap[n].type) {
                    264:        case Dir: case Reg: case Lnk:
                    265:                tossblocks(n);
                    266:        }
                    267:        *dp = nild;
                    268:        imap[n].type = Unalloc;
                    269:        tinode++;
                    270:        if(flags['w'])
                    271:                wrti(n);
                    272: }
                    273: 
                    274: tossblocks(n)
                    275: {      struct dinode *dp;
                    276:        int addr[NADDR], i;
                    277:        dp = (struct dinode *) (buf + (n-1)*sizeof(*dp) + 2*bsize);
                    278:        l3tol(addr, dp->di_addr, NADDR);
                    279:        for(i = 1; i < NADDR-3; i++)
                    280:                if(addr[i]) {
                    281:                        bmap[addr[i]].type = Free;
                    282:                        tfree++;
                    283:                }
                    284:        if(addr[10])
                    285:                freeind(addr[10]);
                    286:        if(addr[11])
                    287:                freedbl(addr[10]);
                    288:        if(addr[12])
                    289:                pmesg("ino %d, triply indirect block?  rerun chuck to fix free list\n",
                    290:                        n);
                    291: }
                    292: 
                    293: freeind(n)
                    294: {      int i, *p;
                    295:        bmap[n].type = Free;
                    296:        if(bread(n, buf, 1))
                    297:                fatal("freeind, could't read block %d\n", n);
                    298:        for(i = 0, p = (int *)buf; i < bsize/sizeof(int); i++, p++)
                    299:                if(*p) {
                    300:                        bmap[*p].type = Free;
                    301:                        tfree++;
                    302:                }
                    303: }
                    304: 
                    305: freedbl(n)
                    306: {      int i, *p;
                    307:        bmap[n].type = Free;
                    308:        if(bread(n, buf+bsize, 1))
                    309:                fatal("freeind2, couldn't read %d\n", n);
                    310:        for(i = 0, p = (int *)(buf+bsize); i < bsize/sizeof(int); i++, p++)
                    311:                if(*p)
                    312:                        freeind(n);
                    313: }
                    314: 
                    315: interact()
                    316: {      int i, j;
                    317:        struct dinode *dp;
                    318:        for(i = 0; i < erptr; i++)
                    319:        switch(erlist[i].type) {
                    320:        default:
                    321:                pmesg("%s not yet doable\n", errnm(erlist[i].type));
                    322:                continue;
                    323:        case Enotdot:
                    324:                pmesg("Enotdot (dot not self) %s\n", prino(erlist[i].a));
                    325:                continue;
                    326:        case Edotino:
                    327:                pmesg("Edotino (dot illegal) %s\n", prino(erlist[i].a));
                    328:                continue;
                    329:        case Enotdotdot:
                    330:                pmesg("Enotdotdot (dotdot illegal) %s\n", prino(erlist[i].a));
                    331:                continue;
                    332:        case Ebadparent:
                    333:                pmesg("Ebadparent (dotdot not parent) %s\n", prino(erlist[i].a));
                    334:                continue;
                    335:        case Elinkcnt:
                    336:                j = erlist[i].a;
                    337:                dp = (struct dinode *) (buf + 2*bsize + (j-1)*sizeof(*dp));
                    338:                pmesg("Elinkcnt, %s, %d links %d refs\n", prino(j), dp->di_nlink,
                    339:                        imap[j].nrefs);
                    340:                if(imap[j].nrefs > 0 || imap[j].type == Weird) 
                    341:                        switch(qry("clri, links-changed-to-refs, skip:\n")) {
                    342:                        case 's':
                    343:                                continue;
                    344:                        case 'c':
                    345:                                pmesg("clearing ino %d\n", j);
                    346:                                clri(j);
                    347:                                continue;
                    348:                        case 'l':
                    349:                                pmesg("fixing links ino %d\n", j);
                    350:                                fixlinks(j);
                    351:                                continue;
                    352:                        }
                    353:                switch(qry("attach to /lost+found, expunge:\n")) {
                    354:                case 'a':
                    355:                        attach(j);
                    356:                        continue;
                    357:                case 'e':
                    358:                        expunge(j);
                    359:                        continue;
                    360:                }
                    361:                continue;
                    362:        case Enullable:
                    363:                j = erlist[i].a;
                    364:                pmesg("Enullable ino %s\n", prino(j));
                    365:                if(qry("clri, or skip\n") == 'c') {
                    366:                        pmesg("clearing ino %d\n", j);
                    367:                        clri(j);
                    368:                }
                    369:                continue;
                    370:        case Einvalid:
                    371:                if(qry("valid flag not set, set it?\n") == 'y') {
                    372:                        sblk.U.B.S_valid = 1;
                    373:                        if(bwrite(1, (char *) &sblk, 1)) 
                    374:                                pmesg("couldn't rewrite super block\n");
                    375:                }
                    376:                continue;
                    377:        }
                    378:        if(qry("fix the super block?\n") == 'y') {
                    379:                pmesg("fixing the superblock\n");
                    380:                fixfree();
                    381:        }
                    382: }

unix.superglobalmegacorp.com

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