Annotation of researchv10no/cmd/chuck/harder.c, revision 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.