Annotation of researchv10dc/lsys/fs/netb.c, revision 1.1

1.1     ! root        1: #include "sys/param.h"
        !             2: #include "sys/user.h"
        !             3: #include "sys/netb.h"
        !             4: #include "sys/inode.h"
        !             5: #include "sys/buf.h"
        !             6: #include "sys/systm.h"
        !             7: #include "sys/stat.h"
        !             8: #include "sys/file.h"
        !             9: #include "sys/conf.h"
        !            10: #include "sys/nbio.h"
        !            11: 
        !            12: static long nbtrannum;
        !            13: static int nbfstyp;
        !            14: int nbdebug;
        !            15: int nbput(), nbupdat(), nbread(), nbwrite(), nbtrunc(), nbstat();
        !            16: int nbnami(), nbioctl(), nbmount(), nbdirread();
        !            17: struct fstypsw nbfs =
        !            18: fsinit(nbput, nbupdat, nbread, nbwrite, nbtrunc, nbstat,
        !            19:        nbnami, nbmount, nbioctl, nullopen, nbdirread);
        !            20: unsigned char *getnbbuf();
        !            21: #define        NBMAXMSG        (5*1024)        /* probably enough */
        !            22: int nbbsz = NBMAXMSG;
        !            23: 
        !            24: /*
        !            25:  * flags in i_un.i_fsflags
        !            26:  * valid only in the root inode
        !            27:  */
        !            28: #define        NBUSY   01              /* already a message outstanding */
        !            29: #define        NWANT   02              /* someone waiting for BUSY */
        !            30: #define        NDEAD   04              /* communication line assumed dead */
        !            31: 
        !            32: /*
        !            33:  * flags valid in any netb inode
        !            34:  */
        !            35: #define        NSTOK   010             /* inode data is fresh; skip next stat message */
        !            36: 
        !            37: nbput(ip)
        !            38: register struct inode *ip;
        !            39: {
        !            40:        unsigned char sbuf[SNBSIZE];
        !            41:        unsigned char rbuf[RNBSIZE];
        !            42:        register unsigned char *sp;
        !            43: 
        !            44: 
        !            45:        /* don't put root, as optimization.  pointless? */
        !            46:        if (ip->i_mpoint->i_mroot == ip)
        !            47:                return;
        !            48:        if(ip->i_flag & ICHG)   /* this is an extra message, but not often? */
        !            49:                nbupdat(ip, &time, &time, 0);
        !            50:        sp = sbuf;
        !            51:        bzero(sp, sizeof(sbuf));
        !            52:        tonetchar(sp, SNB_VERSION, NETB);
        !            53:        tonetchar(sp, SNB_CMD, NBPUT);
        !            54:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !            55:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !            56:        nbsend(ip, sp, rbuf, sizeof(rbuf));
        !            57: }
        !            58: 
        !            59: nbtrunc(ip)
        !            60: register struct inode *ip;
        !            61: {
        !            62:        unsigned char sbuf[SNBSIZE];
        !            63:        unsigned char rbuf[RNBSIZE];
        !            64:        register unsigned char *sp;
        !            65: 
        !            66:        ip->i_un.i_fsflags &=~ NSTOK;
        !            67:        sp = sbuf;
        !            68:        bzero(sp, sizeof(sbuf));
        !            69:        tonetchar(sp, SNB_VERSION, NETB);
        !            70:        tonetchar(sp, SNB_CMD, NBTRNC);
        !            71:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !            72:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !            73:        nbsend(ip, sp, rbuf, sizeof(rbuf));
        !            74: }
        !            75: 
        !            76: /*
        !            77:  * the only times we're interested in are those which have waitfor == 0
        !            78:  * (or those which have ta or tb != &time)
        !            79:  */
        !            80: nbupdat(ip, ta, tb, waitfor)
        !            81: register time_t *ta, *tb;
        !            82: register struct inode *ip;
        !            83: {
        !            84:        unsigned char sbuf[SUPSIZE];
        !            85:        unsigned char rbuf[RNBSIZE];
        !            86:        register unsigned char *sp;
        !            87: 
        !            88:        ip->i_un.i_fsflags &=~ NSTOK;
        !            89:        sp = sbuf;
        !            90:        bzero(sp, sizeof(sbuf));
        !            91:        tonetchar(sp, SNB_VERSION, NETB);
        !            92:        tonetchar(sp, SNB_CMD, NBUPD);
        !            93:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !            94:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !            95:        tonetshort(sp, SUP_MODE, ip->i_mode);
        !            96:        /*
        !            97:         * in theory *ta or *tb could be incremented
        !            98:         * while we are copying them char-by-char
        !            99:         * in practice, it doesn't matter,
        !           100:         * as *t? != &time
        !           101:         */
        !           102:        if((ta != &time) && (ip->i_flag & IACC))
        !           103:                tonetlong(sp, SUP_ATIME, *ta);
        !           104:        if((tb != &time) && (ip->i_flag & IUPD))
        !           105:                tonetlong(sp, SUP_MTIME, *tb);
        !           106:        nbsend(ip, sp, rbuf, sizeof(rbuf));
        !           107:        ip->i_flag &= ~(IUPD|IACC|ICHG);
        !           108: }
        !           109: 
        !           110: /*
        !           111:  * if NSTOK is set,
        !           112:  * the inode is full of stat data from a recent namei
        !           113:  * for stat, NSTOK always set, because we just called namei
        !           114:  * (except for the root, for which namei isn't called)
        !           115:  * for fstat, it is probably not set
        !           116:  */
        !           117: nbstat(ip, ub)
        !           118: register struct inode *ip;
        !           119: struct stat *ub;
        !           120: {
        !           121:        unsigned char sbuf[SSTSIZE];
        !           122:        unsigned char rbuf[RSTSIZE];
        !           123:        struct stat ds;
        !           124:        register unsigned char *p;
        !           125:        long now;
        !           126: 
        !           127:        if ((ip->i_un.i_fsflags & NSTOK) == 0) {
        !           128:                p = sbuf;
        !           129:                bzero(p, sizeof(sbuf));
        !           130:                tonetchar(p, SNB_VERSION, NETB);
        !           131:                tonetchar(p, SNB_CMD, NBSTAT);
        !           132:                tonetlong(p, SNB_LEN, sizeof(sbuf));
        !           133:                tonetlong(p, SNB_TAG, ip->i_un.i_tag);
        !           134:                now = time;             /* in case clock ticks */
        !           135:                tonetlong(p, SST_TIME, now);
        !           136:                nbsend(ip, p, rbuf, sizeof(rbuf));
        !           137:                if(u.u_error)
        !           138:                        return;
        !           139:                p = rbuf;
        !           140:                ip->i_mode = frnetshort(p, RST_MODE);
        !           141:                ip->i_nlink = frnetshort(p, RST_NLINK);
        !           142:                ip->i_uid = frnetshort(p, RST_UID);
        !           143:                ip->i_gid = frnetshort(p, RST_GID);
        !           144:                ip->i_size = frnetlong(p, RST_SIZE);
        !           145:                ip->i_un.i_netatime = frnetlong(p, RST_ATIME);
        !           146:                ip->i_un.i_netmtime = frnetlong(p, RST_MTIME);
        !           147:                ip->i_un.i_netctime = frnetlong(p, RST_CTIME);
        !           148:                ip->i_un.i_netrdev = frnetlong(p, RST_RDEV);
        !           149:        }
        !           150:        ds.st_dev = ip->i_dev;
        !           151:        ds.st_ino = ip->i_number;
        !           152:        ds.st_mode = ip->i_mode;
        !           153:        ds.st_nlink = ip->i_nlink;
        !           154:        ds.st_uid = ip->i_uid;
        !           155:        ds.st_gid = ip->i_gid;
        !           156:        ds.st_size = ip->i_size;
        !           157:        ds.st_atime = ip->i_un.i_netatime;
        !           158:        ds.st_mtime = ip->i_un.i_netmtime;
        !           159:        ds.st_ctime = ip->i_un.i_netctime;
        !           160:        ds.st_rdev = ip->i_un.i_netrdev;
        !           161:        if(copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)))
        !           162:                u.u_error = EFAULT;
        !           163:        ip->i_un.i_fsflags &=~ NSTOK;   /* so repeated fstats check for changes */
        !           164: }
        !           165: 
        !           166: nbread(ip)
        !           167: register struct inode *ip;
        !           168: {
        !           169:        unsigned char sbuf[SRDSIZE];
        !           170:        register unsigned char *rp;
        !           171:        register unsigned char *sp;
        !           172:        register int n;
        !           173: 
        !           174:        ip->i_un.i_fsflags &=~ NSTOK;
        !           175:        rp = getnbbuf();
        !           176:        sp = sbuf;
        !           177:        bzero(sp, sizeof(sbuf));
        !           178:        tonetchar(sp, SNB_VERSION, NETB);
        !           179:        tonetchar(sp, SNB_CMD, NBREAD);
        !           180:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !           181:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !           182:        do {
        !           183:                n = u.u_count;
        !           184:                if(n > nbbsz - RNBSIZE)
        !           185:                        n = nbbsz - RNBSIZE;
        !           186:                tonetlong(sp, SRD_LEN, n);
        !           187:                tonetlong(sp, SRD_OFFSET, Ltol(u.u_offset));
        !           188:                nbsend(ip, sp, rp, nbbsz);
        !           189:                if (u.u_error)
        !           190:                        break;
        !           191:                n = frnetlong(rp, RNB_LEN) - RNBSIZE;
        !           192:                if(n > 0 && n <= nbbsz) /* give it to user */
        !           193:                        iomove(rp + RNBSIZE, n, B_READ);
        !           194:        } while (u.u_error == 0 && u.u_count > 0 && n > 0
        !           195:          &&  frnetchar(rp, RNB_FLAGS) != NBEND);
        !           196:        putnbbuf(rp);
        !           197: }
        !           198: 
        !           199: nbdirread(ip, len)
        !           200: register struct inode *ip;
        !           201: {
        !           202:        unsigned char sbuf[SRDSIZE];
        !           203:        register unsigned char *sp;
        !           204:        register unsigned char *rp;     /* RDISIZE */
        !           205:        int n;
        !           206: 
        !           207:        ip->i_un.i_fsflags &=~ NSTOK;
        !           208:        rp = getnbbuf();
        !           209:        sp = sbuf;
        !           210:        bzero(sp, sizeof(sbuf));
        !           211:        tonetchar(sp, SNB_VERSION, NETB);
        !           212:        tonetchar(sp, SNB_CMD, NBDIR);
        !           213:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !           214:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !           215:        if(len > nbbsz - RDISIZE)
        !           216:                len = nbbsz - RDISIZE;
        !           217:        tonetlong(sp, SRD_LEN, len);
        !           218:        tonetlong(sp, SRD_OFFSET, Ltol(u.u_offset));
        !           219:        nbsend(ip, sp, rp, nbbsz);
        !           220:        if(u.u_error)
        !           221:                goto out;
        !           222:        n = frnetlong(rp, RNB_LEN) - RDISIZE;
        !           223:        if(n > 0) {     /* why not iomove? */
        !           224:                if(u.u_segflg != SEGSYS) {
        !           225:                        if(copyout(rp + RDISIZE, u.u_base, n))
        !           226:                                u.u_error = EFAULT;
        !           227:                }
        !           228:                else
        !           229:                        bcopy(rp + RDISIZE, u.u_base, n);
        !           230:        }
        !           231:        u.u_offset = Lladd(u.u_offset, frnetlong(rp, RDI_USED));
        !           232:        u.u_r.r_val1 = n;
        !           233: out:
        !           234:        putnbbuf(rp);
        !           235: }
        !           236: 
        !           237: nbwrite(ip)
        !           238: register struct inode *ip;
        !           239: {
        !           240:        register unsigned char *sp;
        !           241:        unsigned char rbuf[RNBSIZE];
        !           242:        int n;
        !           243: 
        !           244:        ip->i_un.i_fsflags &=~ NSTOK;
        !           245:        sp = getnbbuf();
        !           246:        bzero(sp, SWRSIZE);
        !           247:        tonetchar(sp, SNB_VERSION, NETB);
        !           248:        tonetchar(sp, SNB_CMD, NBWRT);
        !           249:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !           250:        do {
        !           251:                n = u.u_count;
        !           252:                if(n > nbbsz - SWRSIZE)
        !           253:                        n = nbbsz - SWRSIZE;
        !           254:                tonetlong(sp, SNB_LEN, n + SWRSIZE);
        !           255:                tonetlong(sp, SWR_LEN, n);
        !           256:                tonetlong(sp, SWR_OFFSET, Ltol(u.u_offset));
        !           257:                iomove(sp + SWRSIZE, n, B_WRITE);
        !           258:                if (u.u_error)
        !           259:                        break;
        !           260:                nbsend(ip, sp, rbuf, sizeof(rbuf));
        !           261:                if (u.u_error)
        !           262:                        break;
        !           263:                ip->i_flag |= IUPD|ICHG;
        !           264:        } while(u.u_count > 0);
        !           265:        if(u.u_error == 0)
        !           266:                ip->i_size = frnetlong(rbuf, RNB_FSIZE);
        !           267:        putnbbuf(sp);
        !           268: }
        !           269: 
        !           270: nbioctl(ip, cmd, addr, flag)   /* fp->f_flag */
        !           271: register struct inode *ip;
        !           272: caddr_t addr;
        !           273: {
        !           274:        register unsigned char *p;
        !           275:        int size;
        !           276: 
        !           277:        switch(cmd) {
        !           278:        case NBIOCON:
        !           279:                nbdebug = 1;
        !           280:                return;
        !           281:        case NBIOCOFF:
        !           282:                nbdebug = 0;
        !           283:                return;
        !           284:        case NBIOCBSZ:
        !           285:                if (copyin(addr, (caddr_t)&size, sizeof(size))) {
        !           286:                        u.u_error = EFAULT;
        !           287:                        return;
        !           288:                }
        !           289:                if (size > 1024 && size <= NBMAXMSG)
        !           290:                        nbbsz = size & ~1023;   /* round to even 1K */
        !           291:                if (copyout(addr, (caddr_t)&nbbsz, sizeof(nbbsz)))
        !           292:                        u.u_error = EFAULT;
        !           293:                return;
        !           294:        }
        !           295:        /*
        !           296:         * one buffer, used first for sbuf, then for rbuf
        !           297:         */
        !           298:        p = getnbbuf();
        !           299:        bzero(p, SIOSIZE);
        !           300:        tonetchar(p, SNB_VERSION, NETB);
        !           301:        tonetchar(p, SNB_CMD, NBIOCTL);
        !           302:        tonetlong(p, SNB_LEN, SIOSIZE + SIODATA);
        !           303:        tonetlong(p, SNB_TAG, ip->i_un.i_tag);
        !           304:        tonetlong(p, SIO_CMD, cmd);
        !           305:        tonetshort(p, SIO_FLAG, flag);
        !           306:        if(copyin(addr, p + SIOSIZE, SIODATA)) {
        !           307:                u.u_error = EFAULT;
        !           308:                goto out;
        !           309:        }
        !           310:        nbsend(ip, p, p, RNBSIZE + SIODATA);
        !           311:        if (u.u_error)
        !           312:                goto out;
        !           313:        if(frnetlong(p, RNB_LEN) != RNBSIZE + SIODATA) {
        !           314:                printf("netb: nbioc got %d, not %d\n",
        !           315:                        frnetlong(p, RNB_LEN), RNBSIZE+SIODATA);
        !           316:                u.u_error = EIO;
        !           317:                goto out;
        !           318:        }
        !           319:        if(copyout(p+RNBSIZE, addr, SIODATA))
        !           320:                u.u_error = EFAULT;
        !           321: out:
        !           322:        putnbbuf(p);
        !           323: }
        !           324: 
        !           325: /*
        !           326:  * namei:
        !           327:  * send the whole pathname
        !           328:  * wrong if another filesystem is mounted
        !           329:  * atop some file in this one
        !           330:  */
        !           331: nbnami(p, flagp, follow)
        !           332: register struct nx *p;
        !           333: register struct argnamei *flagp;
        !           334: {
        !           335:        register char *cp;
        !           336:        register struct inode *dp;
        !           337:        register unsigned char *pp;
        !           338:        register int nlen;
        !           339:        int used;
        !           340:        dev_t dev;
        !           341: 
        !           342:        dp = p->dp;
        !           343:        /*
        !           344:         * special case:
        !           345:         * if simple lookup of "" in the root,
        !           346:         * and the connection is dead,
        !           347:         * return OK even though dead so it's possible to unmount
        !           348:         */
        !           349:        if (dp->i_mpoint->i_mroot == dp
        !           350:        &&  dp->i_un.i_fsflags & NDEAD
        !           351:        &&  flagp->flag == NI_SEARCH && *p->cp == 0)
        !           352:                return (0);     /* with the same dp and cp */
        !           353:        /*
        !           354:         * one buffer for rbuf and sbuf
        !           355:         */
        !           356:        pp = getnbbuf();
        !           357:        bzero(pp, SNMSIZE);
        !           358:        tonetchar(pp, SNB_VERSION, NETB);
        !           359:        tonetchar(pp, SNB_CMD, NBNAMI);
        !           360:        tonetlong(pp, SNB_TAG, dp->i_un.i_tag);
        !           361:        cp = p->cp;
        !           362:        while (*cp++)
        !           363:                ;
        !           364:        nlen = cp - p->cp;      /* length of name, including NUL */
        !           365:        if (nlen + SNMSIZE >= nbbsz) {
        !           366:                u.u_error = ENOENT;
        !           367:                goto outnull;
        !           368:        }
        !           369:        used = nlen + SNMSIZE - 1;      /* temporary to improve code */
        !           370:        tonetlong(pp, SNB_LEN, used);
        !           371:        bcopy(p->cp, pp + SNMSIZE, nlen);
        !           372:        tonetchar(pp, SNB_FLAGS, flagp->flag);
        !           373:        switch (flagp->flag) {
        !           374: 
        !           375:        case NI_CREAT:
        !           376:        case NI_NXCREAT:
        !           377:        case NI_MKDIR:
        !           378:                tonetshort(pp, SNM_MODE, flagp->un.mode);
        !           379:                break;
        !           380: 
        !           381:        case NI_LINK:
        !           382:                tonetlong(pp, SNM_INO, flagp->un.il->i_un.i_tag);
        !           383:                break;
        !           384:        }
        !           385:        nbsend(dp, pp, pp, RNMSIZE);
        !           386:        if(u.u_error)
        !           387:                goto outnull;
        !           388:        if (frnetchar(pp, RNB_FLAGS) == NBROOT) {
        !           389:                /* find my root */
        !           390:                dp = dp->i_mpoint;
        !           391:                iput(p->dp);
        !           392:                if(dp == NULL) {
        !           393:                        u.u_error = EGREG;
        !           394:                        goto out;
        !           395:                }
        !           396:                plock(dp);
        !           397:                dp->i_count++;
        !           398:                used = frnetlong(pp, RNM_USED);
        !           399:                if (used < 2 || used >= nlen) {
        !           400:                        u.u_error = EGREG;
        !           401:                        goto outnull;
        !           402:                }
        !           403:                cp = p->cp + used;
        !           404:                *--cp == '.';
        !           405:                *--cp == '.';
        !           406:                p->cp = cp;
        !           407:                goto outmore;
        !           408:        }
        !           409:        switch(flagp->flag) {
        !           410: 
        !           411:        default:
        !           412:                panic("nbnami");
        !           413: 
        !           414:        case NI_CREAT:  /* only case where flagp is used later (creat()) */
        !           415:        case NI_NXCREAT:        /* return an inode, like search */
        !           416:                flagp->un.mode = ~flagp->un.mode;       /* obscure side-effects! */
        !           417:        case NI_SEARCH:
        !           418:                break;
        !           419: 
        !           420:        case NI_DEL:    /* nothing returned */
        !           421:        case NI_LINK:   /* nothing returned */
        !           422:        case NI_MKDIR:  /* nothing returned */
        !           423:        case NI_RMDIR:  /* nothing returned */
        !           424:                goto outnull;
        !           425:        }
        !           426:        /*
        !           427:         * release directory inode, construct a new one
        !           428:         * fill in the attributes even if inode was already in core;
        !           429:         * the new data is more correct (server gets priority)
        !           430:         */
        !           431:        prele(dp);      /* in case new == old */
        !           432:        /* cheat: first character of RNM_DEV == minor */
        !           433:        dev = makedev(major(dp->i_dev), frnetchar(pp, RNM_DEV));
        !           434:        dp = iget(dp, dev, frnetlong(pp, RNM_INO));
        !           435:        /* p->dp == dp before iget was called */
        !           436:        if (dp == NULL) {
        !           437:                idec(p->dp);
        !           438:                goto out;
        !           439:        }
        !           440:        if (p->dp->i_mpoint != dp->i_mpoint) {  /* something mounted here */
        !           441:                idec(p->dp);
        !           442:                p->cp += nlen - 1;      /* point to NUL at the end */
        !           443:                goto outmore;
        !           444:        }
        !           445:        dp->i_un.i_cip = p->dp->i_un.i_cip;
        !           446:        idec(p->dp);
        !           447:        nbunpack(dp, pp);
        !           448:        /*
        !           449:         * no filename to save for accounting; oh well
        !           450:         */
        !           451:        if(flagp->flag == NI_SEARCH && flagp->un.buf)
        !           452:                bcopy("netb exec", flagp->un.buf, flagp->len);
        !           453: 
        !           454:        /*
        !           455:         * return the inode in dp
        !           456:         */
        !           457: out:
        !           458:        p->dp = dp;
        !           459:        putnbbuf(pp);
        !           460:        return (0);
        !           461: 
        !           462:        /*
        !           463:         * discard dp, return NULL
        !           464:         */
        !           465: outnull:
        !           466:        iput(dp);
        !           467:        p->dp = NULL;
        !           468:        putnbbuf(pp);
        !           469:        return (0);
        !           470: 
        !           471:        /*
        !           472:         * crossed to a different filesystem;
        !           473:         * return cp and dp
        !           474:         */
        !           475: outmore:
        !           476:        p->dp = dp;
        !           477:        putnbbuf(pp);
        !           478:        return (1);
        !           479: }
        !           480: 
        !           481: nbmount(cip, dip, flag, mnt, fstyp)
        !           482: struct inode *cip, *dip;
        !           483: {
        !           484: 
        !           485:        nbfstyp = fstyp;
        !           486:        if (mnt)
        !           487:                nbon(cip, dip, flag, fstyp);
        !           488:        else
        !           489:                nboff(dip);
        !           490: }
        !           491: 
        !           492: /*
        !           493:  * mount the filesystem
        !           494:  * fake up a namei message to fetch the root
        !           495:  * don't call nbnami because it's too hard to get
        !           496:  * all the first-time error checks right
        !           497:  */
        !           498: 
        !           499: nbon(cip, dip, flag, fstyp)
        !           500: struct inode *cip;
        !           501: struct inode *dip;
        !           502: {
        !           503:        register struct inode *rip;
        !           504:        struct inode pi;
        !           505:        register unsigned char *pp;
        !           506:        unsigned char sbuf[SNMSIZE+1];
        !           507:        unsigned char rbuf[RNMSIZE];
        !           508:        register dev_t dev;
        !           509: 
        !           510:        if(cip->i_sptr == NULL) {       /* shouting into the storm */
        !           511:                u.u_error = ENXIO;
        !           512:                return;
        !           513:        }
        !           514:        if (dip->i_fstyp == fstyp && major(dip->i_dev) == major(flag)) {
        !           515:                u.u_error = EBUSY;
        !           516:                return;
        !           517:        }
        !           518:        /*
        !           519:         * fake up an inode to represent the connection
        !           520:         * to nbsend and iget
        !           521:         */
        !           522:        pi.i_fstyp = fstyp;
        !           523:        pi.i_mpoint = &pi;
        !           524:        pi.i_mroot = &pi;       /* pi.i_mpoint->i_mroot == &pi */
        !           525:        pi.i_un.i_cip = cip;
        !           526:        pi.i_un.i_fsflags = 0;
        !           527:        pp = sbuf;
        !           528:        bzero(pp, sizeof(sbuf));
        !           529:        tonetchar(pp, SNB_VERSION, NETB);
        !           530:        tonetchar(pp, SNB_CMD, NBNAMI);
        !           531:        tonetlong(pp, SNB_TAG, NBROOTTAG);      /* lookup in the root */
        !           532:        tonetlong(pp, SNB_LEN, SNMSIZE+1);      /* one char of filename */
        !           533:        /* tonetchar(pp, SNMSIZE, 0);           /* "" */
        !           534:        tonetchar(pp, SNB_FLAGS, NI_SEARCH);
        !           535:        nbsend(&pi, pp, rbuf, sizeof(rbuf));
        !           536:        if (u.u_error)
        !           537:                return;
        !           538:        pp = rbuf;
        !           539:        if (frnetchar(pp, RNB_FLAGS) != 0) {
        !           540:                u.u_error = EINVAL;
        !           541:                return;
        !           542:        }
        !           543:        dev = makedev(major(flag), frnetchar(pp, RNM_DEV));
        !           544:        if ((rip = iget(&pi, dev, frnetlong(pp, RNM_INO))) == NULL)
        !           545:                return;
        !           546:        if (rip->i_count != 1) {
        !           547:                iput(rip);
        !           548:                u.u_error = EBUSY;
        !           549:                return;
        !           550:        }
        !           551:        nbunpack(rip, pp);
        !           552:        rip->i_un.i_cip = cip;
        !           553:        dip->i_mroot = rip;
        !           554:        rip->i_mpoint = dip;
        !           555:        prele(rip);
        !           556:        dip->i_count++;
        !           557:        cip->i_count++;
        !           558: }
        !           559: 
        !           560: /*
        !           561:  * unpack inode info from namei response
        !           562:  * a pity stat can't use this too,
        !           563:  * but the stat response isn't quite the same format
        !           564:  */
        !           565: nbunpack(dp, pp)
        !           566: register struct inode *dp;
        !           567: register unsigned char *pp;
        !           568: {
        !           569: 
        !           570:        dp->i_un.i_tag = frnetlong(pp, RNM_TAG);
        !           571:        dp->i_mode = frnetshort(pp, RNM_MODE);
        !           572:        dp->i_nlink = frnetshort(pp, RNM_NLINK);
        !           573:        dp->i_uid = frnetshort(pp, RNM_UID);
        !           574:        dp->i_gid = frnetshort(pp, RNM_GID);
        !           575:        dp->i_size = frnetlong(pp, RNM_SIZE);
        !           576:        dp->i_un.i_netatime = frnetlong(pp, RNM_ATIME);
        !           577:        dp->i_un.i_netmtime = frnetlong(pp, RNM_MTIME);
        !           578:        dp->i_un.i_netctime = frnetlong(pp, RNM_CTIME);
        !           579:        dp->i_un.i_netrdev = frnetlong(pp, RNM_RDEV);
        !           580:        if (dp->i_count == 1)
        !           581:                dp->i_un.i_fsflags = 0;
        !           582:        dp->i_un.i_fsflags |= NSTOK;
        !           583: }
        !           584: 
        !           585: /*
        !           586:  * unmount a netb--
        !           587:  * called from above, or from nbsend when there's an error
        !           588:  * mip is the mount point
        !           589:  * locking needs some thought
        !           590:  */
        !           591: nboff(mip)
        !           592: register struct inode *mip;
        !           593: {
        !           594:        register struct inode *rip;
        !           595: 
        !           596:        rip = mip->i_mroot;
        !           597:        plock(rip);
        !           598:        if (rip->i_mpoint != mip) {     /* already unmounted */
        !           599:                prele(rip);
        !           600:                return;
        !           601:        }
        !           602:        xumount(rip);
        !           603:        iupdat(rip, &time, &time, 1);
        !           604:        ifsinacc(rip);  /* turn all, including rip, to errfs */
        !           605:        plock(mip);             
        !           606:        mip->i_mroot = NULL;
        !           607:        iput(mip);
        !           608:        if (rip->i_un.i_cip == NULL)
        !           609:                panic("nboff");
        !           610:        iput(rip->i_un.i_cip);
        !           611:        iput(rip);      /* errput, not nbput */
        !           612: }
        !           613: 
        !           614: nbsend(ip, sp, rp, size)
        !           615: struct inode *ip;
        !           616: register unsigned char *sp;
        !           617: unsigned char *rp;
        !           618: {
        !           619:        int bad;
        !           620:        long tn;
        !           621:        struct inode *cip;
        !           622:        register struct inode *rip;
        !           623: 
        !           624:        cip = ip->i_un.i_cip;
        !           625:        rip = ip->i_mpoint->i_mroot;
        !           626:        if (rip == NULL || rip->i_fstyp != ip->i_fstyp) {
        !           627:                u.u_error = EIO;
        !           628:                return;
        !           629:        }
        !           630:        while ((rip->i_un.i_fsflags & (NBUSY|NDEAD)) == NBUSY
        !           631:        &&  ip->i_fstyp == nbfstyp) {
        !           632:                rip->i_un.i_fsflags |= NWANT;
        !           633:                if (tsleep((caddr_t)cip, PZERO+1, 0) != TS_OK) {
        !           634:                        u.u_error = EIO;
        !           635:                        return;
        !           636:                }
        !           637:        }
        !           638:        if (ip->i_fstyp != nbfstyp      /* unmounted under us */
        !           639:        ||  rip->i_un.i_fsflags & NDEAD) {      /* or connection fell down */
        !           640:                u.u_error = EIO;
        !           641:                return;
        !           642:        }
        !           643:        rip->i_un.i_fsflags |= NBUSY;
        !           644:        tonetshort(sp, SNB_UID, u.u_uid);
        !           645:        tonetshort(sp, SNB_GID, u.u_gid);
        !           646:        tn = nbtrannum++;
        !           647:        tonetlong(sp, SNB_TRANNUM, tn);
        !           648:        if (istwrite(cip, sp, frnetlong(sp, SNB_LEN)) >= 0
        !           649:        &&  nbrecv(cip, rp, size, tn) >= 0)
        !           650:                bad = 0;
        !           651:        else
        !           652:                bad = 1;
        !           653:        if (ip->i_fstyp == nbfstyp) {   /* in case unmounted while asleep */
        !           654:                rip->i_un.i_fsflags &=~ NBUSY;
        !           655:                if (rip->i_un.i_fsflags & NWANT) {
        !           656:                        wakeup((caddr_t)cip);
        !           657:                        rip->i_un.i_fsflags &=~ NWANT;
        !           658:                }
        !           659:                if (bad)
        !           660:                        rip->i_un.i_fsflags |= NDEAD;
        !           661:        }
        !           662:        if (bad)
        !           663:                u.u_error = EIO;
        !           664:        else if ((bad = frnetshort(rp, RNB_ERRNO)) != 0)
        !           665:                u.u_error = bad;
        !           666: }
        !           667: 
        !           668: /*
        !           669:  * read an answer,
        !           670:  * and make sure it smells like one of ours
        !           671:  */
        !           672: 
        !           673: int
        !           674: nbrecv(cip, rp, size, tn)
        !           675: struct inode *cip;
        !           676: register unsigned char *rp;
        !           677: int size;
        !           678: long tn;
        !           679: {
        !           680:        unsigned char *p;
        !           681:        register int n, len, netlen;
        !           682: 
        !           683: loop:
        !           684:        p = rp;
        !           685:        len = 0;
        !           686:        /*
        !           687:         * header
        !           688:         */
        !           689:        while (len < RNBSIZE) {
        !           690:                n = istread(cip, p, size - len, 0);
        !           691:                if (n <= 0)
        !           692:                        return (-1);
        !           693:                len += n;
        !           694:                p += n;
        !           695:        }
        !           696:        netlen = frnetlong(rp, RNB_LEN);
        !           697:        if (netlen > size || netlen < RNBSIZE) {
        !           698:                printf("netb: rcv len %d\n", netlen);
        !           699:                return (-1);
        !           700:        }
        !           701:        /*
        !           702:         * following data, if any
        !           703:         */
        !           704:        while (len < netlen) {
        !           705:                n = istread(cip, p, size - len, 0);
        !           706:                if (n <= 0)
        !           707:                        return (-1);
        !           708:                len += n;
        !           709:                p += n;
        !           710:        }
        !           711:        if (frnetlong(rp, RNB_TRANNUM) != tn) {
        !           712:                if (frnetlong(rp, RNB_TRANNUM) < tn)    /* echo from the past */
        !           713:                        goto loop;
        !           714:                printf("netb: exp tran %d, got %d\n", tn, frnetlong(rp, RNB_TRANNUM));
        !           715:                return (-1);
        !           716:        }
        !           717:        return (len);
        !           718: }
        !           719: 
        !           720: /* oh no, it's got its own tiny buffer pool: want to avoid breakage on
        !           721:        normal (4k reads for now).  we could replace this with a real
        !           722:        memory manager in the kernel */
        !           723: #define        NBUF    7       /* who knows? */
        !           724: char nb_lock;
        !           725: char nbflgs[NBUF];
        !           726: unsigned char nbbuf[NBUF][NBMAXMSG];
        !           727: 
        !           728: unsigned char *
        !           729: getnbbuf()
        !           730: {
        !           731:        register int i;
        !           732: 
        !           733: loop:
        !           734:        for(i = 0; i < NBUF; i++)
        !           735:                if(!nbflgs[i]) {
        !           736:                        nbflgs[i] = 1;
        !           737:                        return(nbbuf[i]);
        !           738:                }
        !           739:        nb_lock = 1;
        !           740:        sleep((caddr_t)&nb_lock, PZERO);
        !           741:        goto loop;
        !           742: }
        !           743: 
        !           744: putnbbuf(s)
        !           745: unsigned char *s;
        !           746: {
        !           747:        register int i;
        !           748: 
        !           749:        for(i = 0; i < NBUF; i++)
        !           750:                if(nbbuf[i] == s) {
        !           751:                        nbflgs[i] = 0;
        !           752:                        if(nb_lock) {
        !           753:                                nb_lock = 0;
        !           754:                                wakeup((caddr_t) &nb_lock);
        !           755:                        }
        !           756:                        return;
        !           757:                }
        !           758:        panic("putnbbuf");
        !           759: }

unix.superglobalmegacorp.com

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