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

1.1       root        1: #include "fs.h"
                      2: int rerunmsg;
                      3: 
                      4: attach(n)
                      5: {      int lf;
                      6:        char x[24];
                      7:        if(imap[n].type == Unalloc) {
                      8:                pmesg("ino %d is unallocated, not put in lost+found\n", n);
                      9:                return;
                     10:        }
                     11:        pmesg("re-attaching ino %d\n", n);
                     12:        lf = nams(ROOTINO, "lost+found");
                     13:        if(lf <= 0)
                     14:                lf = mkdir(ROOTINO, "lost+found");
                     15:        if(lf <= 0) {
                     16:                pmesg("can't find or create /lost+found.  HELP!\n");
                     17:                exitcode = 1;
                     18:                return;
                     19:        }
                     20:        sprintf(x, "%d", n);
                     21:        if(addtodir(lf, n, x) >= 0) {
                     22:                imap[n].nrefs++;
                     23:                fixlinks(n);
                     24:        }
                     25: }
                     26: 
                     27: mkdir(n, s)
                     28: char *s;
                     29: {      int i, b;
                     30:        struct dinode *dip;
                     31:        struct direct *dp;
                     32:        i = alloci(Dir);
                     33:        dip = (struct dinode *) (buf + 2*bsize + (i-1)*sizeof(*dip));
                     34:        dip->di_mode = (IFDIR | 0777);
                     35:        dip->di_uid = dip->di_gid = 0;
                     36:        b = allocb(i, First);
                     37:        dip->di_nlink = imap[i].nrefs = 2;      /* a little lie */
                     38:        dip->di_ctime = dip->di_mtime = dip->di_atime = time(0);
                     39:        /* now write . and .. */
                     40:        memset(buf, 0, bsize);
                     41:        dp = (struct direct *) buf;
                     42:        dp->d_ino = i;
                     43:        strcpy(dp->d_name, ".");
                     44:        dp++;
                     45:        dp->d_ino = n;
                     46:        strcpy(dp->d_name, "..");
                     47:        if(bwrite(b, buf, 1)) {
                     48:                pmesg("write of new dir blk %d failed\n", b);
                     49:                return(-1);
                     50:        }
                     51:        /* now stick it in its parent */
                     52:        if(addtodir(n, i, "lost+found") >= 0) {
                     53:                wrti(i);
                     54:                return(i);
                     55:        }
                     56:        pmesg("addtodir failed\n");
                     57:        return(-1);
                     58: }
                     59: 
                     60: fndfr(dir, pbno, n)
                     61: int *pbno;
                     62: {      struct direct *dp;
                     63:        int i;
                     64:        if(bread(n, buf, 1)) {
                     65:                pmesg("couldn't read dir block %d\n", n);
                     66:                return(-1);
                     67:        }
                     68:        *pbno = n;
                     69:        dp = (struct direct *) buf;
                     70:        for(i = 0; i < bsize/sizeof(*dp); i++, dp++)
                     71:                if(dp->d_ino == 0)
                     72:                        return(i);
                     73:        return(-1);
                     74: }
                     75: 
                     76: addtodir(dir, ino, s)
                     77: char *s;
                     78: {      int i, bno;
                     79:        struct direct *dp;
                     80:        i = nami(dir, ino);
                     81:        if(i >= 0) {
                     82:                pmesg("ino %d already in dir (%d,%s) (it's ok)\n", ino, dir, prname(dir));
                     83:                /* since you cared enough to ask for it: */
                     84:                imap[ino].parent = dir;
                     85:                return(-1);
                     86:        }
                     87:        i = dirsrch(dir, &bno, fndfr);
                     88:        if(i < 0) {
                     89:                bno = allocb(dir, Other);
                     90:                wrti(dir);
                     91:                memset(buf, 0, bsize);
                     92:                i = 0;
                     93:        }
                     94:        dp = (struct direct *)buf + i;
                     95:        dp->d_ino = ino;
                     96:        strncpy(dp->d_name, s, DIRSIZ);
                     97:        imap[ino].parent = dir;
                     98:        /* if ino was a directory, its wretched pointers are wrong */
                     99:        if(flags['w'] && bwrite(bno, buf, 1) < 0) {
                    100:                pmesg("couldn't rewrite dir block %d\n", bno);
                    101:                return(-1);
                    102:        }
                    103:        if(!rerunmsg++)
                    104:                pmesg("!!counts may be wrong, RERUN chuck!\n");
                    105:        return(0);
                    106: }
                    107: 
                    108: alloci(t)
                    109: {      int i;
                    110:        for(i = 2; i < ninode; i++)
                    111:                if(imap[i].type == Unalloc) {
                    112:                        imap[i].type = t;
                    113:                        /* and adjust some counts? */
                    114:                        return(i);
                    115:                }
                    116:        return(-1);
                    117: }
                    118: 
                    119: /* doesn't understand about holes BUG*/
                    120: allocb(ino, t)
                    121: {      int i, j;
                    122:        long addr[NADDR];
                    123:        struct dinode *dip;
                    124:        dip = (struct dinode *) (buf + 2*bsize + (ino-1)*sizeof(*dip));
                    125:        l3tol(addr, dip->di_addr, NADDR);
                    126:        for(j = 0; j < NADDR-3; j++)    /* secret knowledge!! */
                    127:                if(!addr[j])
                    128:                        break;
                    129:        if(j >= NADDR-3) {
                    130:                pmesg("won't allocate indirect block (bug)%d %d\n");    /* BUG */
                    131:                return(-1);
                    132:        }
                    133:        dip->di_size += 4096;
                    134:        for(i = fblk; i < lblk; i++)
                    135:                if(bmap[i].type == Free) {
                    136:                        bmap[i].ino = ino;
                    137:                        bmap[i].type = t;
                    138:                        addr[j] = i;
                    139:                        ltol3(dip->di_addr, addr, NADDR);
                    140:                        /* and adjust some counts? */
                    141:                        return(i);
                    142:                }
                    143:        pmesg("no more free blocks\n");
                    144:        return(-1);
                    145: }
                    146: 
                    147: expg(dir, x, n)
                    148: {      struct direct *dp;
                    149:        static struct direct nildp;
                    150:        int i;
                    151:        if(bread(n, buf, 1)) {
                    152:                pmesg("expg read block %d failed\n", n);
                    153:                return(-1);
                    154:        }
                    155:        dp = (struct direct *) buf;
                    156:        for(i = 0; i < bsize/sizeof(*dp); i++ , dp++)
                    157:                if(dp->d_ino == x) {
                    158:                        *dp = nildp;
                    159:                        if(flags['w'] && bwrite(n, buf, 1))
                    160:                                pmesg("couldn't rewrite dir block\n");
                    161:                }
                    162:        return(-1);     /* in case it occurs many times in the directory */
                    163: }
                    164: /* remove the ref to the inode from a directory it's in */
                    165: /* if you want more than one, run it lots of times */
                    166: expunge(n)
                    167: {      int i, j;
                    168:        j = imap[n].parent;
                    169:        if(!j || imap[j].type != Dir) {
                    170:                pmesg("parent is %d, not dir\n", j);
                    171:                return(-1);
                    172:        }
                    173:        i = dirsrch(j, n, expg);
                    174: }
                    175: 
                    176: fixdots(ino)
                    177: {      struct dinode *dp = (struct dinode *)(buf + 2*bsize + (ino-1)*sizeof(*dp));
                    178:        int addr[NADDR], i;
                    179:        if(imap[ino].type == Unalloc)   /* someone else really fixed it */
                    180:                return;
                    181:        pmesg("fixdots %s\n", prino(ino));
                    182:        if(imap[ino].type != Dir) {
                    183:                pmesg("fixdir called on non-dir %s\n", prino(ino));
                    184:                return;
                    185:        }
                    186:        /* now redo all the checking and fix everything in sight */
                    187:        l3tol(addr, dp->di_addr, NADDR);
                    188:        if(fixfirst(ino, dp, addr[0]) < 0) {
                    189:                pmesg("too hard, try rerunning chuck\n");
                    190:                exitcode++;
                    191:                rerunmsg++;
                    192:                return;
                    193:        }
                    194:        for(i = 0; i < erptr; i++)
                    195:        switch(erlist[i].type) {
                    196:        case Enotdot: case Edotino: case Enotdotdot: case Ebadparent:
                    197:                if(erlist[i].a == ino)
                    198:                        erlist[i].done = 1;
                    199:        }
                    200: }
                    201: 
                    202: fixfirst(ino, dp, addr)
                    203: struct dinode *dp;
                    204: {      struct direct *d;
                    205:        static struct direct nildir;
                    206:        int i;
                    207:        if(addr < fblk || addr >= lblk) {
                    208:                pmesg("first block address %d bogus\n", addr);  /* FIX */
                    209:                return(-1);
                    210:        }
                    211:        if(bread(addr, buf, 1) < 0) {
                    212:                pmesg("couldn't read %d\n", addr);
                    213:                return(-1);
                    214:        }
                    215:        d = (struct direct *) buf;
                    216:        if(firstspace() < 0)    /* make space at beginning for . and .. */
                    217:                return(-1);
                    218:        /* this strategy may leave some link counts wrong, FIX */
                    219:        /* also, who made dp->d_size large enough? FIX */
                    220:        *d = nildir;
                    221:        d->d_ino = ino;
                    222:        strcpy(d->d_name, ".");
                    223:        d++;
                    224:        i = imap[ino].parent;   /* what if we are a directory? FIX */
                    225:        if(i < ROOTINO || i >= ninode) {
                    226:                pmesg("parent is %d, and so illegal\n", i);
                    227:                return(-1);
                    228:        }
                    229:        *d = nildir;
                    230:        d->d_ino = i;
                    231:        strcpy(d->d_name, "..");
                    232:        if(flags['w'] && bwrite(addr, buf, 1) < 0) {
                    233:                pmesg("couldn't rewrite %d\n");
                    234:                return(-1);
                    235:        }
                    236:        return(0);
                    237: }
                    238: 
                    239: firstspace()
                    240: {      struct direct *dp = (struct direct *)buf;
                    241:        int i, cnt, baddot, baddotdot, fa, fb;
                    242:        for(fa = fb = cnt = i = 0; i < bsize/sizeof(*dp); i++) {
                    243:                if(dp->d_ino)
                    244:                        continue;
                    245:                cnt++;
                    246:                if(!fa) {
                    247:                        fa = i;
                    248:                        continue;
                    249:                }
                    250:                if(!fb)
                    251:                        fb = i;
                    252:        }
                    253:        dp = (struct direct *) buf;
                    254:        baddot = strcmp(dp->d_name, ".");
                    255:        baddotdot = strcmp(dp[1].d_name, "..");
                    256:        if(cnt - baddot - baddotdot < 0) {
                    257:                pmesg("first block of directory overfull\n");
                    258:                return(-1);     /* too hard FIX */
                    259:        }
                    260:        if(baddot)
                    261:                dp[fa] = dp[0];
                    262:        if(baddotdot)
                    263:                dp[fb] = dp[1];
                    264:        return(0);
                    265: }
                    266: 
                    267: xfxnm(dir, ret, n)
                    268: int *ret;
                    269: {      struct direct *dp;
                    270:        int i, j, cnt = 0;
                    271:        if(bread(n, buf, 1)) {
                    272:                pmesg("dir %d couldn't read dir block %d\n", dir, n);
                    273:                return(*ret = -1);
                    274:        }
                    275:        dp = (struct direct *)buf;
                    276:        for(i = 0; i < bsize/sizeof(*dp); i++, dp++) {
                    277:                if(!dp->d_ino)
                    278:                        continue;
                    279:                if(dp->d_ino == dir && dp->d_name[0] != '.') {  /* FIX */
                    280:                        dp->d_ino = 0;  /* dirs can't refer to themselves */
                    281:                        /* link count now wrong, in safe direction */
                    282:                }
                    283:                if(dp->d_ino < 1 || dp->d_ino >= ninode)
                    284:                        dp->d_ino = 0;  /* bad inumber */
                    285:                if(imap[dp->d_ino].type == Unalloc) {   /* ambitious FIX*/
                    286:                        if(cnt++ == 10)
                    287:                                pmesg("...\n");
                    288:                        else if(cnt < 10)
                    289:                                pmesg("dir entry %d,%.16s unalloc inode\n", dp->d_ino,
                    290:                                        dp->d_name);
                    291:                        dp->d_ino = 0;
                    292:                }
                    293:                for(j = 0; j < DIRSIZ; j++) {
                    294:                        if(!dp->d_name[j])
                    295:                                break;
                    296:                        if(dp->d_name[j] & 0x80) {      /* ascii! */
                    297:                                dp->d_name[j] &= 0x7f;
                    298:                                j--;    /* did we zero it? */
                    299:                                continue;
                    300:                        }
                    301:                }
                    302:                if(j == 0) {
                    303:                        pmesg("ino %d in dir %d had no name\n", dp->d_ino, dir);
                    304:                        pmesg("being called #%d\n", dp->d_ino);
                    305:                        sprintf(dp->d_name, "#%d", dp->d_ino);
                    306:                        continue;
                    307:                }
                    308:                for(; j < DIRSIZ;j++)
                    309:                        dp->d_name[j] = 0;
                    310:        }
                    311:        if(flags['w'] && bwrite(n, buf, 1)) {
                    312:                pmesg("couldn't rewrite blk %d ino %d\n", n, dir);
                    313:                return(*ret = -1);
                    314:        }
                    315:        return(-1);
                    316: }
                    317: fixnames(ino)
                    318: {      int retcode = 0, j;
                    319:        (void) dirsrch(ino, &retcode, xfxnm);
                    320:        if(retcode < 0) {
                    321:                pmesg("fixnames failed\n");
                    322:                return;
                    323:        }
                    324:        for(j = 0; j < erptr; j++)
                    325:                if(erlist[j].type == Ebadname && erlist[j].a == ino)
                    326:                        erlist[j].done = 1;
                    327: }

unix.superglobalmegacorp.com

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