Annotation of researchv10dc/sys/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: /*
        !           167:  * here and in nbwrite, `tonetlong(..., Ltol(u.u_offset))' is OK.
        !           168:  * it looks like four function calls, one per byte,
        !           169:  * but Ltol is a macro without side effects.
        !           170:  * maybe there should just be a temporary for clarity
        !           171:  */
        !           172: nbread(ip)
        !           173: register struct inode *ip;
        !           174: {
        !           175:        unsigned char sbuf[SRDSIZE];
        !           176:        register unsigned char *rp;
        !           177:        register unsigned char *sp;
        !           178:        register int n;
        !           179: 
        !           180:        ip->i_un.i_fsflags &=~ NSTOK;
        !           181:        rp = getnbbuf();
        !           182:        sp = sbuf;
        !           183:        bzero(sp, sizeof(sbuf));
        !           184:        tonetchar(sp, SNB_VERSION, NETB);
        !           185:        tonetchar(sp, SNB_CMD, NBREAD);
        !           186:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !           187:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !           188:        do {
        !           189:                n = u.u_count;
        !           190:                if(n > nbbsz - RNBSIZE)
        !           191:                        n = nbbsz - RNBSIZE;
        !           192:                tonetlong(sp, SRD_LEN, n);
        !           193:                tonetlong(sp, SRD_OFFSET, Ltol(u.u_offset));
        !           194:                nbsend(ip, sp, rp, nbbsz);
        !           195:                if (u.u_error)
        !           196:                        break;
        !           197:                n = frnetlong(rp, RNB_LEN) - RNBSIZE;
        !           198:                if(n > 0 && n <= nbbsz) /* give it to user */
        !           199:                        iomove(rp + RNBSIZE, n, B_READ);
        !           200:        } while (u.u_error == 0 && u.u_count > 0 && n > 0
        !           201:          &&  frnetchar(rp, RNB_FLAGS) != NBEND);
        !           202:        putnbbuf(rp);
        !           203: }
        !           204: 
        !           205: nbdirread(ip, len)
        !           206: register struct inode *ip;
        !           207: {
        !           208:        unsigned char sbuf[SRDSIZE];
        !           209:        register unsigned char *sp;
        !           210:        register unsigned char *rp;     /* RDISIZE */
        !           211:        int n;
        !           212:        llong_t oldoff;
        !           213:        long netoff;    /* just the 32-bit part */
        !           214: 
        !           215:        ip->i_un.i_fsflags &=~ NSTOK;
        !           216:        rp = getnbbuf();
        !           217:        sp = sbuf;
        !           218:        bzero(sp, sizeof(sbuf));
        !           219:        tonetchar(sp, SNB_VERSION, NETB);
        !           220:        tonetchar(sp, SNB_CMD, NBDIR);
        !           221:        tonetlong(sp, SNB_LEN, sizeof(sbuf));
        !           222:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !           223:        if(len > nbbsz - RDISIZE)
        !           224:                len = nbbsz - RDISIZE;
        !           225:        tonetlong(sp, SRD_LEN, len);
        !           226:        oldoff = u.u_offset;
        !           227:        netoff = Ltol(u.u_offset);
        !           228:        tonetlong(sp, SRD_OFFSET, netoff);
        !           229:        nbsend(ip, sp, rp, nbbsz);
        !           230:        if(u.u_error)
        !           231:                goto out;
        !           232:        n = frnetlong(rp, RNB_LEN) - RDISIZE;
        !           233:        if (n > 0 && n <= nbbsz)
        !           234:                iomove(rp + RDISIZE, n, B_READ);
        !           235:        if (u.u_error)
        !           236:                goto out;
        !           237:        u.u_offset = Lladd(oldoff, frnetlong(rp, RDI_USED));
        !           238:        u.u_r.r_val1 = n;
        !           239: out:
        !           240:        putnbbuf(rp);
        !           241: }
        !           242: 
        !           243: nbwrite(ip)
        !           244: register struct inode *ip;
        !           245: {
        !           246:        register unsigned char *sp;
        !           247:        unsigned char rbuf[RNBSIZE];
        !           248:        int n;
        !           249: 
        !           250:        ip->i_un.i_fsflags &=~ NSTOK;
        !           251:        sp = getnbbuf();
        !           252:        bzero(sp, SWRSIZE);
        !           253:        tonetchar(sp, SNB_VERSION, NETB);
        !           254:        tonetchar(sp, SNB_CMD, NBWRT);
        !           255:        tonetlong(sp, SNB_TAG, ip->i_un.i_tag);
        !           256:        do {
        !           257:                n = u.u_count;
        !           258:                if(n > nbbsz - SWRSIZE)
        !           259:                        n = nbbsz - SWRSIZE;
        !           260:                tonetlong(sp, SNB_LEN, n + SWRSIZE);
        !           261:                tonetlong(sp, SWR_LEN, n);
        !           262:                tonetlong(sp, SWR_OFFSET, Ltol(u.u_offset));
        !           263:                iomove(sp + SWRSIZE, n, B_WRITE);
        !           264:                if (u.u_error)
        !           265:                        break;
        !           266:                nbsend(ip, sp, rbuf, sizeof(rbuf));
        !           267:                if (u.u_error)
        !           268:                        break;
        !           269:                ip->i_flag |= IUPD|ICHG;
        !           270:        } while(u.u_count > 0);
        !           271:        if(u.u_error == 0)
        !           272:                ip->i_size = frnetlong(rbuf, RNB_FSIZE);
        !           273:        putnbbuf(sp);
        !           274: }
        !           275: 
        !           276: nbioctl(ip, cmd, addr, flag)   /* fp->f_flag */
        !           277: register struct inode *ip;
        !           278: caddr_t addr;
        !           279: {
        !           280:        register unsigned char *p;
        !           281:        int size;
        !           282: 
        !           283:        switch(cmd) {
        !           284:        case NBIOCON:
        !           285:                nbdebug = 1;
        !           286:                return;
        !           287:        case NBIOCOFF:
        !           288:                nbdebug = 0;
        !           289:                return;
        !           290:        case NBIOCBSZ:
        !           291:                if (copyin(addr, (caddr_t)&size, sizeof(size))) {
        !           292:                        u.u_error = EFAULT;
        !           293:                        return;
        !           294:                }
        !           295:                if (size > 1024 && size <= NBMAXMSG)
        !           296:                        nbbsz = size & ~1023;   /* round to even 1K */
        !           297:                if (copyout(addr, (caddr_t)&nbbsz, sizeof(nbbsz)))
        !           298:                        u.u_error = EFAULT;
        !           299:                return;
        !           300:        }
        !           301:        /*
        !           302:         * one buffer, used first for sbuf, then for rbuf
        !           303:         */
        !           304:        p = getnbbuf();
        !           305:        bzero(p, SIOSIZE);
        !           306:        tonetchar(p, SNB_VERSION, NETB);
        !           307:        tonetchar(p, SNB_CMD, NBIOCTL);
        !           308:        tonetlong(p, SNB_LEN, SIOSIZE + SIODATA);
        !           309:        tonetlong(p, SNB_TAG, ip->i_un.i_tag);
        !           310:        tonetlong(p, SIO_CMD, cmd);
        !           311:        tonetshort(p, SIO_FLAG, flag);
        !           312:        if(copyin(addr, p + SIOSIZE, SIODATA)) {
        !           313:                u.u_error = EFAULT;
        !           314:                goto out;
        !           315:        }
        !           316:        nbsend(ip, p, p, RNBSIZE + SIODATA);
        !           317:        if (u.u_error)
        !           318:                goto out;
        !           319:        if(frnetlong(p, RNB_LEN) != RNBSIZE + SIODATA) {
        !           320:                printf("netb: nbioc got %d, not %d\n",
        !           321:                        frnetlong(p, RNB_LEN), RNBSIZE+SIODATA);
        !           322:                u.u_error = EIO;
        !           323:                goto out;
        !           324:        }
        !           325:        if(copyout(p+RNBSIZE, addr, SIODATA))
        !           326:                u.u_error = EFAULT;
        !           327: out:
        !           328:        putnbbuf(p);
        !           329: }
        !           330: 
        !           331: /*
        !           332:  * namei:
        !           333:  * send the whole pathname
        !           334:  * wrong if another filesystem is mounted
        !           335:  * atop some file in this one
        !           336:  */
        !           337: nbnami(p, flagp, follow)
        !           338: register struct nx *p;
        !           339: register struct argnamei *flagp;
        !           340: {
        !           341:        register char *cp;
        !           342:        register struct inode *dp;
        !           343:        register unsigned char *pp;
        !           344:        register int nlen;
        !           345:        int used;
        !           346:        dev_t dev;
        !           347: 
        !           348:        dp = p->dp;
        !           349:        /*
        !           350:         * special case:
        !           351:         * if simple lookup of "" in the root,
        !           352:         * and the connection is dead,
        !           353:         * return OK even though dead so it's possible to unmount
        !           354:         */
        !           355:        if (dp->i_mpoint->i_mroot == dp
        !           356:        &&  dp->i_un.i_fsflags & NDEAD
        !           357:        &&  flagp->flag == NI_SEARCH && *p->cp == 0)
        !           358:                return (0);     /* with the same dp and cp */
        !           359:        /*
        !           360:         * one buffer for rbuf and sbuf
        !           361:         */
        !           362:        pp = getnbbuf();
        !           363:        bzero(pp, SNMSIZE);
        !           364:        tonetchar(pp, SNB_VERSION, NETB);
        !           365:        tonetchar(pp, SNB_CMD, NBNAMI);
        !           366:        tonetlong(pp, SNB_TAG, dp->i_un.i_tag);
        !           367:        cp = p->cp;
        !           368:        while (*cp++)
        !           369:                ;
        !           370:        nlen = cp - p->cp;      /* length of name, including NUL */
        !           371:        if (nlen + SNMSIZE >= nbbsz) {
        !           372:                u.u_error = ENOENT;
        !           373:                goto outnull;
        !           374:        }
        !           375:        used = nlen + SNMSIZE - 1;      /* temporary to improve code */
        !           376:        tonetlong(pp, SNB_LEN, used);
        !           377:        bcopy(p->cp, pp + SNMSIZE, nlen);
        !           378:        tonetchar(pp, SNB_FLAGS, flagp->flag);
        !           379:        switch (flagp->flag) {
        !           380: 
        !           381:        case NI_CREAT:
        !           382:        case NI_NXCREAT:
        !           383:        case NI_MKDIR:
        !           384:                tonetshort(pp, SNM_MODE, flagp->un.mode);
        !           385:                break;
        !           386: 
        !           387:        case NI_LINK:
        !           388:                tonetlong(pp, SNM_INO, flagp->un.il->i_un.i_tag);
        !           389:                break;
        !           390:        }
        !           391:        nbsend(dp, pp, pp, RNMSIZE);
        !           392:        if(u.u_error)
        !           393:                goto outnull;
        !           394:        if (frnetchar(pp, RNB_FLAGS) == NBROOT) {
        !           395:                /* find my root */
        !           396:                dp = dp->i_mpoint;
        !           397:                iput(p->dp);
        !           398:                if(dp == NULL) {
        !           399:                        u.u_error = EGREG;
        !           400:                        goto out;
        !           401:                }
        !           402:                plock(dp);
        !           403:                dp->i_count++;
        !           404:                used = frnetlong(pp, RNM_USED);
        !           405:                if (used < 2 || used >= nlen) {
        !           406:                        u.u_error = EGREG;
        !           407:                        goto outnull;
        !           408:                }
        !           409:                cp = p->cp + used;
        !           410:                *--cp == '.';
        !           411:                *--cp == '.';
        !           412:                p->cp = cp;
        !           413:                goto outmore;
        !           414:        }
        !           415:        switch(flagp->flag) {
        !           416: 
        !           417:        default:
        !           418:                panic("nbnami");
        !           419: 
        !           420:        case NI_CREAT:  /* only case where flagp is used later (creat()) */
        !           421:        case NI_NXCREAT:        /* return an inode, like search */
        !           422:                flagp->un.mode = ~flagp->un.mode;       /* obscure side-effects! */
        !           423:        case NI_SEARCH:
        !           424:                break;
        !           425: 
        !           426:        case NI_DEL:    /* nothing returned */
        !           427:        case NI_LINK:   /* nothing returned */
        !           428:        case NI_MKDIR:  /* nothing returned */
        !           429:        case NI_RMDIR:  /* nothing returned */
        !           430:                goto outnull;
        !           431:        }
        !           432:        /*
        !           433:         * release directory inode, construct a new one
        !           434:         * fill in the attributes even if inode was already in core;
        !           435:         * the new data is more correct (server gets priority)
        !           436:         */
        !           437:        prele(dp);      /* in case new == old */
        !           438:        /* cheat: first character of RNM_DEV == minor */
        !           439:        dev = makedev(major(dp->i_dev), frnetchar(pp, RNM_DEV));
        !           440:        dp = iget(dp, dev, frnetlong(pp, RNM_INO));
        !           441:        /* p->dp == dp before iget was called */
        !           442:        if (dp == NULL) {
        !           443:                idec(p->dp);
        !           444:                goto out;
        !           445:        }
        !           446:        if (p->dp->i_mpoint != dp->i_mpoint) {  /* something mounted here */
        !           447:                idec(p->dp);
        !           448:                p->cp += nlen - 1;      /* point to NUL at the end */
        !           449:                goto outmore;
        !           450:        }
        !           451:        dp->i_un.i_cip = p->dp->i_un.i_cip;
        !           452:        idec(p->dp);
        !           453:        nbunpack(dp, pp);
        !           454:        /*
        !           455:         * no filename to save for accounting; oh well
        !           456:         */
        !           457:        if(flagp->flag == NI_SEARCH && flagp->un.buf)
        !           458:                bcopy("netb exec", flagp->un.buf, flagp->len);
        !           459: 
        !           460:        /*
        !           461:         * return the inode in dp
        !           462:         */
        !           463: out:
        !           464:        p->dp = dp;
        !           465:        putnbbuf(pp);
        !           466:        return (0);
        !           467: 
        !           468:        /*
        !           469:         * discard dp, return NULL
        !           470:         */
        !           471: outnull:
        !           472:        iput(dp);
        !           473:        p->dp = NULL;
        !           474:        putnbbuf(pp);
        !           475:        return (0);
        !           476: 
        !           477:        /*
        !           478:         * crossed to a different filesystem;
        !           479:         * return cp and dp
        !           480:         */
        !           481: outmore:
        !           482:        p->dp = dp;
        !           483:        putnbbuf(pp);
        !           484:        return (1);
        !           485: }
        !           486: 
        !           487: nbmount(cip, dip, flag, mnt, fstyp)
        !           488: struct inode *cip, *dip;
        !           489: {
        !           490: 
        !           491:        nbfstyp = fstyp;
        !           492:        if (mnt)
        !           493:                nbon(cip, dip, flag, fstyp);
        !           494:        else
        !           495:                nboff(dip);
        !           496: }
        !           497: 
        !           498: /*
        !           499:  * data structures for keeping track of device numbers in use
        !           500:  */
        !           501: #define        NDEVS   256
        !           502: static char nbdevs[NDEVS];
        !           503: 
        !           504: #define        D_SET(dev)      nbdevs[dev] = 1
        !           505: #define        D_CLR(dev)      nbdevs[dev] = 0
        !           506: #define        D_ISSET(dev)    nbdevs[dev]
        !           507: 
        !           508: /*
        !           509:  * mount the filesystem
        !           510:  * fake up a namei message to fetch the root
        !           511:  * don't call nbnami because it's too hard to get
        !           512:  * all the first-time error checks right
        !           513:  */
        !           514: 
        !           515: nbon(cip, dip, flag, fstyp)
        !           516: struct inode *cip;
        !           517: struct inode *dip;
        !           518: {
        !           519:        register struct inode *rip;
        !           520:        struct inode pi;
        !           521:        register unsigned char *pp;
        !           522:        unsigned char sbuf[SNMSIZE+1];
        !           523:        unsigned char rbuf[RNMSIZE];
        !           524:        register int dmaj;
        !           525: 
        !           526:        if(cip->i_sptr == NULL) {       /* shouting into the storm */
        !           527:                u.u_error = ENXIO;
        !           528:                return;
        !           529:        }
        !           530:        for (dmaj = 0; dmaj < NDEVS; dmaj++)
        !           531:                if (D_ISSET(dmaj) == 0)
        !           532:                        break;
        !           533:        if (dmaj >= NDEVS) {
        !           534:                u.u_error = EMFILE;
        !           535:                return;
        !           536:        }
        !           537:        D_SET(dmaj);
        !           538:        /*
        !           539:         * fake up an inode to represent the connection
        !           540:         * to nbsend and iget
        !           541:         */
        !           542:        pi.i_fstyp = fstyp;
        !           543:        pi.i_mpoint = &pi;
        !           544:        pi.i_mroot = &pi;       /* pi.i_mpoint->i_mroot == &pi */
        !           545:        pi.i_un.i_cip = cip;
        !           546:        pi.i_un.i_fsflags = 0;
        !           547:        pp = sbuf;
        !           548:        bzero(pp, sizeof(sbuf));
        !           549:        tonetchar(pp, SNB_VERSION, NETB);
        !           550:        tonetchar(pp, SNB_CMD, NBNAMI);
        !           551:        tonetlong(pp, SNB_TAG, NBROOTTAG);      /* lookup in the root */
        !           552:        tonetlong(pp, SNB_LEN, SNMSIZE+1);      /* one char of filename */
        !           553:        /* tonetchar(pp, SNMSIZE, 0);           /* "" */
        !           554:        tonetchar(pp, SNB_FLAGS, NI_SEARCH);
        !           555:        nbsend(&pi, pp, rbuf, sizeof(rbuf));
        !           556:        if (u.u_error) {
        !           557:                D_CLR(dmaj);
        !           558:                return;
        !           559:        }
        !           560:        pp = rbuf;
        !           561:        if (frnetchar(pp, RNB_FLAGS) != 0) {
        !           562:                D_CLR(dmaj);
        !           563:                u.u_error = EINVAL;
        !           564:                return;
        !           565:        }
        !           566:        if ((rip = iget(&pi, makedev(dmaj, frnetchar(pp, RNM_DEV)), frnetlong(pp, RNM_INO))) == NULL) {
        !           567:                D_CLR(dmaj);
        !           568:                return;
        !           569:        }
        !           570:        if (rip->i_count != 1) {
        !           571:                printf("nbon busy, dev %d\n", dmaj);    /* shouldn't happen */
        !           572:                iput(rip);
        !           573:                D_CLR(dmaj);
        !           574:                u.u_error = EBUSY;
        !           575:                return;
        !           576:        }
        !           577:        nbunpack(rip, pp);
        !           578:        rip->i_un.i_cip = cip;
        !           579:        dip->i_mroot = rip;
        !           580:        rip->i_mpoint = dip;
        !           581:        prele(rip);
        !           582:        dip->i_count++;
        !           583:        cip->i_count++;
        !           584: }
        !           585: 
        !           586: /*
        !           587:  * unpack inode info from namei response
        !           588:  * a pity stat can't use this too,
        !           589:  * but the stat response isn't quite the same format
        !           590:  */
        !           591: nbunpack(dp, pp)
        !           592: register struct inode *dp;
        !           593: register unsigned char *pp;
        !           594: {
        !           595: 
        !           596:        dp->i_un.i_tag = frnetlong(pp, RNM_TAG);
        !           597:        dp->i_mode = frnetshort(pp, RNM_MODE);
        !           598:        dp->i_nlink = frnetshort(pp, RNM_NLINK);
        !           599:        dp->i_uid = frnetshort(pp, RNM_UID);
        !           600:        dp->i_gid = frnetshort(pp, RNM_GID);
        !           601:        dp->i_size = frnetlong(pp, RNM_SIZE);
        !           602:        dp->i_un.i_netatime = frnetlong(pp, RNM_ATIME);
        !           603:        dp->i_un.i_netmtime = frnetlong(pp, RNM_MTIME);
        !           604:        dp->i_un.i_netctime = frnetlong(pp, RNM_CTIME);
        !           605:        dp->i_un.i_netrdev = frnetlong(pp, RNM_RDEV);
        !           606:        if (dp->i_count == 1)
        !           607:                dp->i_un.i_fsflags = 0;
        !           608:        dp->i_un.i_fsflags |= NSTOK;
        !           609: }
        !           610: 
        !           611: /*
        !           612:  * unmount a netb--
        !           613:  * mip is the mount point
        !           614:  * locking needs some thought
        !           615:  */
        !           616: nboff(mip)
        !           617: register struct inode *mip;
        !           618: {
        !           619:        register struct inode *rip;
        !           620: 
        !           621:        rip = mip->i_mroot;
        !           622:        plock(rip);
        !           623:        if (rip->i_mpoint != mip) {     /* already unmounted */
        !           624:                prele(rip);
        !           625:                return;
        !           626:        }
        !           627:        xumount(rip);
        !           628:        iupdat(rip, &time, &time, 1);
        !           629:        ifsinacc(rip);  /* turn all, including rip, to errfs */
        !           630:        plock(mip);             
        !           631:        mip->i_mroot = NULL;
        !           632:        iput(mip);
        !           633:        if (rip->i_un.i_cip == NULL)
        !           634:                panic("nboff");
        !           635:        iput(rip->i_un.i_cip);
        !           636:        D_CLR(major(rip->i_dev));
        !           637:        iput(rip);      /* errput, not nbput */
        !           638: }
        !           639: 
        !           640: nbsend(ip, sp, rp, size)
        !           641: struct inode *ip;
        !           642: register unsigned char *sp;
        !           643: unsigned char *rp;
        !           644: {
        !           645:        int bad;
        !           646:        long tn;
        !           647:        struct inode *cip;
        !           648:        register struct inode *rip;
        !           649: 
        !           650:        cip = ip->i_un.i_cip;
        !           651:        rip = ip->i_mpoint->i_mroot;
        !           652:        if (rip == NULL || rip->i_fstyp != ip->i_fstyp) {
        !           653:                u.u_error = EIO;
        !           654:                return;
        !           655:        }
        !           656:        while ((rip->i_un.i_fsflags & (NBUSY|NDEAD)) == NBUSY
        !           657:        &&  ip->i_fstyp == nbfstyp) {
        !           658:                rip->i_un.i_fsflags |= NWANT;
        !           659:                if (tsleep((caddr_t)cip, PZERO+1, 0) != TS_OK) {
        !           660:                        u.u_error = EIO;
        !           661:                        return;
        !           662:                }
        !           663:        }
        !           664:        if (ip->i_fstyp != nbfstyp      /* unmounted under us */
        !           665:        ||  rip->i_un.i_fsflags & NDEAD) {      /* or connection fell down */
        !           666:                u.u_error = EIO;
        !           667:                return;
        !           668:        }
        !           669:        rip->i_un.i_fsflags |= NBUSY;
        !           670:        tonetshort(sp, SNB_UID, u.u_uid);
        !           671:        tonetshort(sp, SNB_GID, u.u_gid);
        !           672:        tn = nbtrannum++;
        !           673:        tonetlong(sp, SNB_TRANNUM, tn);
        !           674:        if (istwrite(cip, sp, frnetlong(sp, SNB_LEN)) >= 0
        !           675:        &&  nbrecv(cip, rp, size, tn) >= 0)
        !           676:                bad = 0;
        !           677:        else
        !           678:                bad = 1;
        !           679:        if (ip->i_fstyp == nbfstyp) {   /* in case unmounted while asleep */
        !           680:                rip->i_un.i_fsflags &=~ NBUSY;
        !           681:                if (rip->i_un.i_fsflags & NWANT) {
        !           682:                        wakeup((caddr_t)cip);
        !           683:                        rip->i_un.i_fsflags &=~ NWANT;
        !           684:                }
        !           685:                if (bad)
        !           686:                        rip->i_un.i_fsflags |= NDEAD;
        !           687:        }
        !           688:        if (bad)
        !           689:                u.u_error = EIO;
        !           690:        else if ((bad = frnetshort(rp, RNB_ERRNO)) != 0)
        !           691:                u.u_error = bad;
        !           692: }
        !           693: 
        !           694: /*
        !           695:  * read an answer,
        !           696:  * and make sure it smells like one of ours
        !           697:  */
        !           698: 
        !           699: int
        !           700: nbrecv(cip, rp, size, tn)
        !           701: struct inode *cip;
        !           702: register unsigned char *rp;
        !           703: int size;
        !           704: long tn;
        !           705: {
        !           706:        unsigned char *p;
        !           707:        register int n, len, netlen;
        !           708: 
        !           709: loop:
        !           710:        p = rp;
        !           711:        len = 0;
        !           712:        /*
        !           713:         * header
        !           714:         */
        !           715:        while (len < RNBSIZE) {
        !           716:                n = istread(cip, p, size - len, 0);
        !           717:                if (n <= 0)
        !           718:                        return (-1);
        !           719:                len += n;
        !           720:                p += n;
        !           721:        }
        !           722:        netlen = frnetlong(rp, RNB_LEN);
        !           723:        if (netlen > size || netlen < RNBSIZE) {
        !           724:                printf("netb: rcv len %d\n", netlen);
        !           725:                return (-1);
        !           726:        }
        !           727:        /*
        !           728:         * following data, if any
        !           729:         */
        !           730:        while (len < netlen) {
        !           731:                n = istread(cip, p, size - len, 0);
        !           732:                if (n <= 0)
        !           733:                        return (-1);
        !           734:                len += n;
        !           735:                p += n;
        !           736:        }
        !           737:        if (frnetlong(rp, RNB_TRANNUM) != tn) {
        !           738:                if (frnetlong(rp, RNB_TRANNUM) < tn)    /* echo from the past */
        !           739:                        goto loop;
        !           740:                printf("netb: exp tran %d, got %d\n", tn, frnetlong(rp, RNB_TRANNUM));
        !           741:                return (-1);
        !           742:        }
        !           743:        return (len);
        !           744: }
        !           745: 
        !           746: /* oh no, it's got its own tiny buffer pool: want to avoid breakage on
        !           747:        normal (4k reads for now).  we could replace this with a real
        !           748:        memory manager in the kernel */
        !           749: #define        NBUF    7       /* who knows? */
        !           750: char nb_lock;
        !           751: char nbflgs[NBUF];
        !           752: unsigned char nbbuf[NBUF][NBMAXMSG];
        !           753: 
        !           754: unsigned char *
        !           755: getnbbuf()
        !           756: {
        !           757:        register int i;
        !           758: 
        !           759: loop:
        !           760:        for(i = 0; i < NBUF; i++)
        !           761:                if(!nbflgs[i]) {
        !           762:                        nbflgs[i] = 1;
        !           763:                        return(nbbuf[i]);
        !           764:                }
        !           765:        nb_lock = 1;
        !           766:        sleep((caddr_t)&nb_lock, PZERO);
        !           767:        goto loop;
        !           768: }
        !           769: 
        !           770: putnbbuf(s)
        !           771: unsigned char *s;
        !           772: {
        !           773:        register int i;
        !           774: 
        !           775:        for(i = 0; i < NBUF; i++)
        !           776:                if(nbbuf[i] == s) {
        !           777:                        nbflgs[i] = 0;
        !           778:                        if(nb_lock) {
        !           779:                                nb_lock = 0;
        !           780:                                wakeup((caddr_t) &nb_lock);
        !           781:                        }
        !           782:                        return;
        !           783:                }
        !           784:        panic("putnbbuf");
        !           785: }

unix.superglobalmegacorp.com

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