Annotation of researchv10dc/lsys/fs/netb.c, revision 1.1.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.