## diffname port/devmnt.c 1990/0227 ## diff -e /dev/null /n/bootesdump/1990/0227/sys/src/9/mips/devmnt.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "errno.h" #include "devtab.h" #include "fcall.h" /* * Easy version: multiple sessions but no intra-session multiplexing, copy the data */ typedef struct Mnt Mnt; struct Mnt { Ref; /* for number of chans, incl. mntpt but not msg */ QLock; /* for access */ Chan *msg; /* for reading and writing messages */ Chan *mntpt; /* channel in user's name space */ }; #define BUFSIZE (MAXFDATA+500) /* BUG */ typedef struct Mntbuf Mntbuf; struct Mntbuf { Mntbuf *next; char buf[BUFSIZE]; }; struct { Lock; Mntbuf *free; }mntbufalloc; typedef struct Mnthdr Mnthdr; struct Mnthdr /* next only meaningful when buffer isn't being used */ { Mnthdr *next; Fcall thdr; Fcall rhdr; }; struct { Lock; Mnthdr *free; }mnthdralloc; Mnt *mnt; void mntxmit(Mnt*, Mnthdr*); Mntbuf* mballoc(void) { Mntbuf *mb; loop: lock(&mntbufalloc); if(mb = mntbufalloc.free){ /* assign = */ mntbufalloc.free = mb->next; unlock(&mntbufalloc); return mb; } unlock(&mntbufalloc); print("no mntbufs\n"); if(u == 0) panic("mballoc"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); goto loop; } void mbfree(Mntbuf *mb) { lock(&mntbufalloc); mb->next = mntbufalloc.free; mntbufalloc.free = mb; unlock(&mntbufalloc); } Mnthdr* mhalloc(void) { Mnthdr *mh; loop: lock(&mnthdralloc); if(mh = mnthdralloc.free){ /* assign = */ mnthdralloc.free = mh->next; unlock(&mnthdralloc); return mh; } unlock(&mnthdralloc); print("no mnthdrs\n"); if(u == 0) panic("mballoc"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); goto loop; } void mhfree(Mnthdr *mh) { lock(&mnthdralloc); mh->next = mnthdralloc.free; mnthdralloc.free = mh; unlock(&mnthdralloc); } Mnt* mntdev(int dev, int noerr) { Mnt *m; if(dev<0 || conf.nmntdev<=dev){ if(noerr) return 0; panic("mntdev out of range"); } m = &mnt[dev]; if(m->msg == 0){ if(noerr) return 0; error(0, Eshutdown); } return m; } void mntreset(void) { int i; Mntbuf *mb; Mnthdr *mh; mnt = ialloc(conf.nmntdev*sizeof(Mnt), 0); mb = ialloc(conf.nmntbuf*sizeof(Mntbuf), 0); for(i=0; iref == 0) goto Found; unlock(m); } error(0, Enomntdev); Found: m->ref = 1; unlock(m); c = devattach('M', spec); c->dev = m - mnt; m->mntpt = c; cm = bogus.chan; m->msg = cm; incref(cm); mh = mhalloc(); if(waserror()){ mhfree(mh); close(c); nexterror(); } mh->thdr.type = Tattach; mh->thdr.fid = c->fid; memcpy(mh->thdr.uname, u->p->pgrp->user, NAMELEN); strcpy(mh->thdr.aname, spec); mntxmit(m, mh); c->qid = mh->rhdr.qid; mhfree(mh); poperror(); return c; } Chan* mntclone(Chan *c, Chan *nc) { Mnt *m; Mnthdr *mh; int new; new = 0; if(nc == 0){ nc = newchan(); new = 1; if(waserror()){ close(nc); nexterror(); } } m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Tclone; mh->thdr.fid = c->fid; mh->thdr.newfid = nc->fid; mntxmit(m, mh); nc->type = c->type; nc->dev = c->dev; nc->qid = c->qid; nc->mode = c->mode; nc->flag = c->flag; nc->offset = c->offset; nc->mnt = c->mnt; if(new) poperror(); mhfree(mh); poperror(); incref(m); return nc; } int mntwalk(Chan *c, char *name) { Mnt *m; Mnthdr *mh; int found; found = 1; m = mntdev(c->dev, 0); mh = mhalloc(); mh->thdr.type = Twalk; mh->thdr.fid = c->fid; strcpy(mh->thdr.name, name); if(waserror()){ /* BUG: can check type of error? */ found = 0; goto Out; } mntxmit(m, mh); c->qid = mh->rhdr.qid; poperror(); Out: mhfree(mh); return found; } void mntstat(Chan *c, char *dp) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Tstat; mh->thdr.fid = c->fid; mntxmit(m, mh); memcpy(dp, mh->rhdr.stat, DIRLEN); dp[DIRLEN-4] = devchar[c->type]; dp[DIRLEN-3] = 0; dp[DIRLEN-2] = c->dev; dp[DIRLEN-1] = c->dev>>8; mhfree(mh); poperror(); } Chan* mntopen(Chan *c, int omode) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Topen; mh->thdr.fid = c->fid; mh->thdr.mode = omode; mntxmit(m, mh); c->qid = mh->rhdr.qid; mhfree(mh); poperror(); c->offset = 0; c->mode = openmode(omode); c->flag |= COPEN; return c; } void mntcreate(Chan *c, char *name, int omode, ulong perm) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Tcreate; mh->thdr.fid = c->fid; strcpy(mh->thdr.name, name); mh->thdr.mode = omode; mh->thdr.perm = perm; mntxmit(m, mh); c->qid = mh->rhdr.qid; mhfree(mh); poperror(); c->flag |= COPEN; c->mode = openmode(omode); c->qid = mh->rhdr.qid; } void mntclose(Chan *c) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Tclunk; mh->thdr.fid = c->fid; mntxmit(m, mh); mhfree(mh); if(c == m->mntpt) m->mntpt = 0; if(decref(m) == 0){ /* BUG: need to hang up all pending i/o */ qlock(m); close(m->msg); m->msg = 0; qunlock(m); } poperror(); } long mntreadwrite(Chan *c, void *vbuf, long n, int type) { Mnt *m; Mnthdr *mh; long nt, nr, count, offset; char *buf; buf = vbuf; count = 0; offset = c->offset; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = type; mh->thdr.fid = c->fid; Loop: nt = n; if(nt > MAXFDATA) nt = MAXFDATA; mh->thdr.offset = offset; mh->thdr.count = nt; mh->thdr.data = buf; mntxmit(m, mh); nr = mh->rhdr.count; offset += nr; count += nr; buf += nr; n -= nr; if(n && nr==nt) goto Loop; mhfree(mh); poperror(); return count; } long mntread(Chan *c, void *buf, long n) { long i; uchar *b; n = mntreadwrite(c, buf, n, Tread); if(c->qid & CHDIR){ b = (uchar*)buf; for(i=n-DIRLEN; i>=0; i-=DIRLEN){ b[DIRLEN-4] = devchar[c->type]; b[DIRLEN-3] = 0; b[DIRLEN-2] = c->dev; b[DIRLEN-1] = c->dev>>8; b += DIRLEN; } } return n; } long mntwrite(Chan *c, void *buf, long n) { return mntreadwrite(c, buf, n, Twrite); } void mntremove(Chan *c) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Tremove; mh->thdr.fid = c->fid; mntxmit(m, mh); mhfree(mh); poperror(); } void mntwstat(Chan *c, char *dp) { Mnt *m; Mnthdr *mh; m = mntdev(c->dev, 0); mh = mhalloc(); if(waserror()){ mhfree(mh); nexterror(); } mh->thdr.type = Twstat; mh->thdr.fid = c->fid; memcpy(mh->thdr.stat, dp, DIRLEN); mntxmit(m, mh); mhfree(mh); poperror(); } void mnterrstr(Error *e, char *buf) { Mnt *m; Mnthdr *mh; char *def="mounted device shut down"; m = mntdev(e->dev, 1); if(m == 0){ strcpy(buf, def); return; } mh = mhalloc(); if(waserror()){ strcpy(buf, def); mhfree(mh); nexterror(); } mh->thdr.type = Terrstr; mh->thdr.fid = 0; mh->thdr.err = e->code; mntxmit(m, mh); strcpy(buf, (char*)mh->rhdr.ename); mhfree(mh); poperror(); } void mntuserstr(Error *e, char *buf) { Mnt *m; Mnthdr *mh; char *def="mounted device shut down"; m = mntdev(e->dev, 1); if(m == 0){ strcpy(buf, def); return; } mh = mhalloc(); if(waserror()){ strcpy(buf, def); mhfree(mh); nexterror(); } mh->thdr.type = Tuserstr; mh->thdr.fid = 0; mh->thdr.uid = e->code; mntxmit(m, mh); strcpy(buf, (char*)mh->rhdr.uname); mhfree(mh); poperror(); } void mntxmit(Mnt *m, Mnthdr *mh) { ulong n; Mntbuf *mbr, *mbw; Chan *mntpt; mbr = mballoc(); mbw = mballoc(); if(waserror()){ mbfree(mbr); mbfree(mbw); nexterror(); } n = convS2M(&mh->thdr, mbw->buf); qlock(m); if(m->msg == 0){ qunlock(m); error(0, Eshutdown); } qlock(m->msg); if(waserror()){ qunlock(m); qunlock(m->msg); nexterror(); } if((*devtab[m->msg->type].write)(m->msg, mbw->buf, n) != n){ pprint("short write in mntxmit\n"); error(0, Egreg); } /* * Read response */ n = (*devtab[m->msg->type].read)(m->msg, mbr->buf, BUFSIZE); qunlock(m); qunlock(m->msg); poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ pprint("format error in mntxmit\n"); error(0, Egreg); } /* * Various checks */ if(mh->rhdr.type != mh->thdr.type+1){ pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(0, Egreg); } if(mh->rhdr.fid != mh->thdr.fid){ pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(0, Egreg); } if(mh->rhdr.err){ mntpt = m->mntpt; /* unsafe, but Errors are unsafe anyway */ if(mntpt) error(mntpt, mh->rhdr.err); error(0, Eshutdown); } /* * Copy out on read */ if(mh->thdr.type == Tread) memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); mbfree(mbr); mbfree(mbw); poperror(); } . ## diffname port/devmnt.c 1990/0303 ## diff -e /n/bootesdump/1990/0227/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0303/sys/src/9/mips/devmnt.c 245a nc->mchan = c->mchan; nc->mqid = c->qid; . 207a c->mchan = m->msg; c->mqid = c->qid; . 191c c->dev = m->mntid; . 189a lock(&mntid); m->mntid = ++mntid.id; unlock(&mntid); . 123,134c for(m=mnt,i=0; imntid == dev){ if(m->msg == 0) break; return m; } if(noerr) return 0; error(0, Eshutdown); . 121a int i; . 52a struct { Lock; long id; }mntid; . 20a ulong mntid; /* serial # */ . ## diffname port/devmnt.c 1990/0306 ## diff -e /n/bootesdump/1990/0303/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0306/sys/src/9/mips/devmnt.c 587c if(!isbit) qunlock(m->msg); . 574c if(!isbit) qunlock(m->msg); . 571c isbit = 0; if(devchar[m->msg->type] == 'b') isbit = 1; if(!isbit) qlock(m->msg); . 556a int isbit; . ## diffname port/devmnt.c 1990/03081 ## diff -e /n/bootesdump/1990/0306/sys/src/9/mips/devmnt.c /n/bootesdump/1990/03081/sys/src/9/mips/devmnt.c 591,594c n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); if(isbit) close(msg); else{ qunlock(m); qunlock(msg); } . 583c if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ . 578,580c if(isbit) close(msg); else{ qunlock(m); qunlock(msg); } . 575,576c /* * Avoid qlock for bit, to maximize parallelism */ if(isbit){ lock(&m->use); /* spin rather than sleep */ if((msg = m->msg) == 0){ unlock(&m->use); error(0, Eshutdown); } incref(msg); unlock(&m->use); }else{ qlock(m); if((msg = m->msg) == 0){ qunlock(m); error(0, Eshutdown); } qlock(msg); } . 567,571d 556c Chan *mntpt, *msg; . ## diffname port/devmnt.c 1990/0310 ## diff -e /n/bootesdump/1990/03081/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0310/sys/src/9/mips/devmnt.c 384a print("close mount table %d\n", m->mntid); . ## diffname port/devmnt.c 1990/0312 ## diff -e /n/bootesdump/1990/0310/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0312/sys/src/9/mips/devmnt.c 470a decref(m); . ## diffname port/devmnt.c 1990/0322 ## diff -e /n/bootesdump/1990/0312/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0322/sys/src/9/mips/devmnt.c 612c qunlock(&m->q); . 595c qunlock(&m->q); . 586c qunlock(&m->q); . 584c qlock(&m->q); . 582c unlock(&m->q); . 578c unlock(&m->q); . 576c lock(&m->q); /* spin rather than sleep */ . 389c qunlock(&m->q); . 386c qlock(&m->q); . 20c QLock q; /* for access */ . ## diffname port/devmnt.c 1990/0324 ## diff -e /n/bootesdump/1990/0322/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0324/sys/src/9/mips/devmnt.c 612c qunlock(m); . 595c qunlock(m); . 586c qunlock(m); . 584c qlock(m); . 582c unlock(&m->use); . 578c unlock(&m->use); . 576c lock(&m->use); /* spin rather than sleep */ . 570c if(devchar[m->msg->type] == '3') . 389c qunlock(m); . 386c qlock(m); . 20c QLock; /* for access */ . ## diffname port/devmnt.c 1990/0409 ## diff -e /n/bootesdump/1990/0324/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0409/sys/src/9/mips/devmnt.c 385d ## diffname port/devmnt.c 1990/0511 ## diff -e /n/bootesdump/1990/0409/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0511/sys/src/9/mips/devmnt.c 613a if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){ pprint("short write in mntxmit\n"); error(0, Egreg); } /* * Read response */ n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE); qunlock(m); qunlock(msg); . 612a nexterror(); . 611a error(0, Eshutdown); } qlock(msg); if(waserror()){ qunlock(m); . 608,610c close(msg); poperror(); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ pprint("format error in mntxmit\n"); error(0, Egreg); } /* * Various checks */ if(mh->rhdr.type != mh->thdr.type+1){ pprint("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(0, Egreg); } if(mh->rhdr.fid != mh->thdr.fid){ pprint("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(0, Egreg); } if(mh->rhdr.err){ mntpt = m->mntpt; /* unsafe, but Errors are unsafe anyway */ if(mntpt) error(mntpt, mh->rhdr.err); error(0, Eshutdown); } /* * Copy out on read */ if(mh->thdr.type == Tread) memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); mbfree(mbr); mbfree(mbw); poperror(); return; Normal: qlock(m); if((msg = m->msg) == 0){ . 591,596c close(msg); . 589a incref(msg); unlock(&m->use); . 582,588c error(0, Eshutdown); . 574,580c if(devchar[m->msg->type] != '3') goto Normal; lock(&m->use); /* spin rather than sleep */ if((msg = m->msg) == 0){ . 572c * Bit3 does its own multiplexing. (Well, the file server does.) * The code is different enough that it's broken out separately here. . 568,570d 558d ## diffname port/devmnt.c 1990/0513 ## diff -e /n/bootesdump/1990/0511/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0513/sys/src/9/mips/devmnt.c 261a if(new) poperror(); . 258,259d ## diffname port/devmnt.c 1990/0604 ## diff -e /n/bootesdump/1990/0513/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0604/sys/src/9/mips/devmnt.c 659,669c Respond: mqfree(q); poperror(); . 645,656c if(q->reader == 0){ /* i will read */ q->reader = u->p; Read: qunlock(q); qlocked = 0; n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE); if(convM2S(mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); mnterrdequeue(q, mh); error(0, Ebadmsg); } /* * Response might not be mine */ qlock(q); qlocked = 1; if(mh->rhdr.fid == mh->thdr.fid && mh->rhdr.type == mh->thdr.type+1){ /* it's mine */ q->reader = 0; if(w = q->writer){ /* advance a writer to reader */ q->reader = w->p; q->writer = w->next; wakeup(&w->r); } qunlock(q); qlocked = 0; goto Respond; } /* * Hand response to correct recipient */ if(q->writer == 0) print("response with empty queue\n"); for(ow=0,w=q->writer; w; ow=w,w=w->next) if(mh->rhdr.fid == w->thdr.fid && mh->rhdr.type == w->thdr.type+1){ Mntbuf *t; t = mbr; mbr = w->mbr; w->mbr = t; memcpy(&w->rhdr, &mh->rhdr, sizeof mh->rhdr); /* take recipient from queue */ if(ow == 0) q->writer = w->next; else ow->next = w->next; wakeup(&w->r); goto Read; } goto Read; }else{ mh->mbr = mbr; mh->p = u->p; /* put self in queue */ mh->next = q->writer; q->writer = mh; qunlock(q); qlocked = 0; if(waserror()){ /* interrupted sleep */ print("interrupted i/o\n"); mnterrdequeue(q, mh); nexterror(); } sleep(&mh->r, return0, 0); poperror(); qlock(q); qlocked = 1; if(q->reader == u->p) /* i got promoted */ goto Read; mbr = mh->mbr; /* pick up my buffer */ qunlock(q); qlocked = 0; goto Respond; . 641,643c if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){ print("short write in mntxmit\n"); error(0, Eshortmsg); . 637,638c if(qlocked) qunlock(q); mqfree(q); . 630,635c #endif incref(q); qlock(q); qlocked = 1; . 609,610c print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(0, Ebadmsg); . 605,606c print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(0, Ebadmsg); . 597,598c print("format error in mntxmit\n"); error(0, Ebadmsg); . 592,593c n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE); mqfree(q); . 584,586c if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){ print("short write in mntxmit\n"); error(0, Eshortmsg); . 581c mqfree(q); . 573,579c incref(q); . 571c if(devchar[q->msg->type] != '3') . 566a q = m->q; if(q == 0) error(0, Eshutdown); #ifdef BIT3 . 557c Mnthdr *w, *ow; Chan *mntpt; MntQ *q; int qlocked; . 552a mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ { Mnthdr *w; qlock(q); /* take self from queue if necessary */ if(q->reader == u->p){ /* advance a writer to reader */ w = q->writer; if(w){ q->reader = w->p; q->writer = w->next; wakeup(&w->r); }else{ q->reader = 0; q->writer = 0; } }else{ w = q->writer; if(w == mh) q->writer = w->next; else{ while(w){ if(w->next == mh){ w->next = mh->next; break; } w = w->next; } } } qunlock(q); } void . 461,475c mntclunk(c, Tremove); . 392a void mntclose(Chan *c) { mntclunk(c, Tclunk); } . 384,389c lock(m); if(--m->ref == 0){ /* BUG: need to hang up all pending i/o */ q = m->q; m->q = 0; m->mntid = 0; unlock(m); /* mqfree can take time */ mqfree(q); }else unlock(m); if(waserr) nexterror(); . 380c waserr = 0; if(waserror()) /* gotta clean up as if there wasn't */ waserr = 1; else mntxmit(m, mh); . 374,378c mh->thdr.type = t; . 370a MntQ *q; int waserr; int ne = u->nerrlab; . 367c mntclunk(Chan *c, int t) . 216c c->mchan = m->q->msg; . 206a mqfree(q); . 203a out: . 202c /* * Look for queue to same msg channel */ q = mntqalloc.arena; for(i=0; imsg==cm){ lock(q); if(q->ref && q->msg==cm){ m->q = q; q->ref++; unlock(q); goto out; } unlock(q); } m->q = mqalloc(); m->q->msg = cm; . 191a . 174a MntQ *q; . 173c Mnt *m, *mm; . 161a mq = ialloc(conf.nmntdev*sizeof(MntQ), 0); for(i=0; iq == 0) . 124a MntQ* mqalloc(void) { MntQ *q; lock(&mntqalloc); if(q = mntqalloc.free){ /* assign = */ mntqalloc.free = q->next; unlock(&mntqalloc); lock(q); q->ref = 1; q->writer = 0; q->reader = 0; unlock(q); return q; } unlock(&mntqalloc); panic("no mntqs\n"); /* there MUST be enough */ } void mqfree(MntQ *mq) { Chan *msg = 0; lock(mq); if(--mq->ref == 0){ msg = mq->msg; mq->msg = 0; lock(&mntqalloc); mq->next = mntqalloc.free; mntqalloc.free = mq; unlock(&mntqalloc); } unlock(mq); if(msg) /* after locks are down */ close(msg); } . 109c panic("mhalloc"); . 56a MntQ *arena; MntQ *free; }mntqalloc; struct { Lock; . 45a Rendez r; Proc *p; Mntbuf *mbr; . 43c Mnthdr *next; /* in free list or writers list */ . 40,41c struct Mnthdr . 25a struct MntQ { Ref; QLock; /* for access */ MntQ *next; /* for allocation */ Chan *msg; /* for reading and writing messages */ Proc *reader; /* process reading response */ Mnthdr *writer; /* queue of headers of written messages */ }; . 23a MntQ *q; . 22d 20d 16a typedef struct Mnthdr Mnthdr; typedef struct MntQ MntQ; . 12,14d ## diffname port/devmnt.c 1990/0617 ## diff -e /n/bootesdump/1990/0604/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0617/sys/src/9/mips/devmnt.c 825c print("%lux interrupted i/o %d %d\n", u->p, mh->thdr.type, mh->thdr.fid); . 798c if(q->writer == 0) print("response with empty queue %d %d %d: %d %d\n", mh->rhdr.type, mh->rhdr.err, mh->rhdr.fid, mh->thdr.type, mh->thdr.fid); . 774c print("%lux %lux %lux %d format error in mntxmit %s\n", u->p, q->reader, q->writer, n, u->p->text); . 289a unlock(&mntqalloc); . 285,287c m->q = mqalloc(cm); . 273a lock(&mntqalloc); . 169a print("mqfree %lux %lux\n", mq->reader, mq->writer); . 159d 156d 153a q->msg = msg; unlock(q); incref(msg); . 151d 148d 144c mqalloc(Chan *msg) /* mntqalloc is locked */ . ## diffname port/devmnt.c 1990/0619 ## diff -e /n/bootesdump/1990/0617/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0619/sys/src/9/mips/devmnt.c 855c mbfree(mh->mbr); . 835d 825c print("interrupted i/o\n"); . 817d 803,804c t = mh->mbr; mh->mbr = w->mbr; . 798c if(q->writer==0) print("response with empty queue\n"); . 772,774c n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); . 747c mbfree(mh->mbr); . 719c if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ . 715c n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); . 686c mbfree(mh->mbr); . 683c mh->mbr = mballoc(); . 677c Mntbuf *mbw; . 289c qunlock(&mntqalloc); . 274c qlock(&mntqalloc); . 169d 144c mqalloc(Chan *msg) /* mntqalloc is qlocked */ . 67a QLock; . ## diffname port/devmnt.c 1990/0623 ## diff -e /n/bootesdump/1990/0619/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0623/sys/src/9/mips/devmnt.c 824d 798d 774d ## diffname port/devmnt.c 1990/0629 ## diff -e /n/bootesdump/1990/0623/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0629/sys/src/9/mips/devmnt.c 812a print("devmnt: undelivered response fid %d type %d\n", mh->rhdr.fid, mh->rhdr.type); print("reader pid %d fid %d type %d\n", u->p->pid, mh->thdr.fid, mh->thdr.type); for(w=q->writer; w; w=w->next)print("writer pid %d fid %d type %d\n",w->p->pid,w->thdr.fid,w->thdr.type); . ## diffname port/devmnt.c 1990/0703 ## diff -e /n/bootesdump/1990/0629/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0703/sys/src/9/mips/devmnt.c 853a } . 852c if(mh->thdr.type == Tread){ if(mh->rhdr.count > mh->thdr.count) error(0, Ebadcnt); . 813,816d 772a poperror(); . 771a if(waserror()){ mnterrdequeue(q, mh); nexterror(); } . ## diffname port/devmnt.c 1990/0717 ## diff -e /n/bootesdump/1990/0703/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0717/sys/src/9/mips/devmnt.c 860a } mntdump() { int i; MntQ *q; Mnthdr *h; Proc *p; for(i=0; imsg) continue; p = q->reader; print("q rdr %d wrtr ", p? p->pid : 0); for(h=q->writer; h; h=h->next) print("(%lux %lux %d)", h, &h->r, (p=h->p)? p->pid : 0); print("\n"); } . 830c sleep(&mh->r, mntreadreply, mh); . 814a w->readreply = 1; . 792a w->readreply = 1; . 762a mh->readreply = 0; . 672a int mntreadreply(void *a) { return ((Mnthdr *)a)->readreply; } . 56a int readreply; /* true if we are reader or our reply has come */ . ## diffname port/devmnt.c 1990/0725 ## diff -e /n/bootesdump/1990/0717/sys/src/9/mips/devmnt.c /n/bootesdump/1990/0725/sys/src/9/mips/devmnt.c 294d ## diffname port/devmnt.c 1990/1002 ## diff -e /n/bootesdump/1990/0725/sys/src/9/mips/devmnt.c /n/bootesdump/1990/1002/sys/src/9/mips/devmnt.c 751a } . 750c if(mh->thdr.type == Tread){ if(mh->rhdr.count>497 && mh->rhdr.data[497]==011) print("*497==11 %lux\n", &mh->rhdr.data[497]); . ## diffname port/devmnt.c 1990/1004 ## diff -e /n/bootesdump/1990/1002/sys/src/9/mips/devmnt.c /n/bootesdump/1990/1004/sys/src/9/mips/devmnt.c 754d 750,752c if(mh->thdr.type == Tread) . ## diffname port/devmnt.c 1990/11211 ## diff -e /n/bootesdump/1990/1004/sys/src/9/mips/devmnt.c /n/bootesdump/1990/11211/sys/src/9/mips/devmnt.c 863c error(Ebadcnt); . 852,856c if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); error(Eshutdown); . 810,811c if(mh->rhdr.tag == w->thdr.tag){ . 793,794c if(mh->rhdr.tag == mh->thdr.tag){ /* it's mine */ . 786c error(Ebadmsg); . 771c error(Eshortmsg); . 740,745d 738c error(Ebadmsg); . 734c error(Ebadmsg); . 731a if(mh->rhdr.tag != mh->thdr.tag){ print("tag mismatch %d %d\n", mh->rhdr.tag, mh->thdr.tag); error(Ebadmsg); } if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); error(Eshutdown); } . 726c error(Ebadmsg); . 714c error(Eshortmsg); . 698c error(Eshutdown); . 684d 677a . 672a . 585,638d 540c if(c->qid.path & CHDIR){ . 300c strcpy(mh->thdr.aname, bogus.spec); strcpy(mh->thdr.auth, bogus.auth); . 266c c = devattach('M', bogus.spec); . 258c error(Enomntdev); . 248,249c bogus = *((struct bogus *)crud); . 245a char *auth; . 236c mntattach(char *crud) . 219a mh[i].thdr.tag = i; . 218a mh[i].thdr.tag = i; } . 217c for(i=0; iprev = 0; mh->writing = 1; if(q->writer) q->writer->prev = mh; . 761,776c if(tag<0 || tag>=conf.nmnthdr){ print("unknown tag %d\n", tag); goto Read; } w = &mnthdralloc.arena[tag]; if(!w->writing){ print("reply not writing\n"); goto Read; } t = mh->mbr; mh->mbr = w->mbr; w->mbr = t; memcpy(&w->rhdr, &mh->rhdr, sizeof mh->rhdr); mntwunlink(q, w); w->readreply = 1; wakeup(&w->r); . 750a if(q->writer) q->writer->prev = 0; . 746c tag = mh->rhdr.tag; if(tag == mh->thdr.tag){ /* it's mine */ . 636c int qlocked, tag; . 633c Mntbuf *mbw, *t; . 605,618c }else mntwunlink(q, mh); . 599a q->writer->prev = 0; . 590a if(w->next) w->next->prev = w->prev; if(w->prev) w->prev->next = w->next; else{ q->writer = w->next; if(q->writer) q->writer->prev = 0; } w->writing = 0; } void mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */ { . 589c mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */ . 221a mnthdralloc.arena = mh; . 61a Mnthdr *arena; . 50c Mnthdr *next; /* in free list or writers list */ Mnthdr *prev; /* in writers list only */ int writing; /* flag: in writers list */ . ## diffname port/devmnt.c 1990/1124 ## diff -e /n/bootesdump/1990/1123/sys/src/9/mips/devmnt.c /n/bootesdump/1990/1124/sys/src/9/mips/devmnt.c 833c poperror(); /* 1 */ . 821a }else if(mh->rhdr.type != mh->thdr.type+1){ print("bad type %d not %d in mntxmit\n", mh->rhdr.type, mh->thdr.type+1); error(Ebadmsg); . 817c poperror(); /* 2 */ . 809a mh->active = 0; . 801c mnterrdequeue(m, mh); . 794d 780d 777,778c if(w->flushing || !w->active) /* nothing to do; mntflush will clean up */ . 764a mh->active = 0; . 759,761d 757a mntwunlink(q, w); . 746c print("bad reply message\n"); mnterrdequeue(m, mh); . 744c poperror(); /* 3 */ . 739,740c if(waserror()){ /* 3 */ mnterrdequeue(m, mh); . 729a mh->active = 1; . 723c if(waserror()){ /* 2 */ . 715c poperror(); /* 1 */ . 680c poperror(); /* 2 */ . 666c if(waserror()){ /* 2 */ . 648c if(waserror()){ /* 1 */ . 644c int qlocked, tag, written; . 628c mntflush(m, mh); . 618,619d 616a mntwunlink(q, w); . 611a mh->flushing = 1; q = m->q; . 610a MntQ *q; . 609a Mnthdr *mh; if(omh->thdr.type == Tflush) return; mh = mhalloc(); if(waserror()){ omh->flushing = 0; mhfree(mh); return; /* no more errors please */ } mh->thdr.type = Tflush; mh->thdr.oldtag = omh->thdr.tag; mntxmit(m, mh); omh->flushing = 0; mhfree(mh); poperror(); } void mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */ { . 608c mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ . 606a /* * m->q is unlocked. Send Tflush message to flush omh->tag. * Cut off all errors. Caller will free omh */ . 604d 140a if(mh->flushing) return; mh->active = 0; . 124a mh->flushing = 0; . 52c short active; short flushing; /* a Tflush has been sent */ . ## diffname port/devmnt.c 1990/1126 ## diff -e /n/bootesdump/1990/1124/sys/src/9/mips/devmnt.c /n/bootesdump/1990/1126/sys/src/9/mips/devmnt.c 472d ## diffname port/devmnt.c 1990/1127 ## diff -e /n/bootesdump/1990/1126/sys/src/9/mips/devmnt.c /n/bootesdump/1990/1127/sys/src/9/mips/devmnt.c 811,813c w->mbr = mh->mbr; mh->mbr = 0; . 774a mh->mbr = mballoc(); . 708a mh->mbr = mballoc(); . 680c if(mh->mbr) mbfree(mh->mbr); . 677c mh->mbr = 0; . 672c Mntbuf *mbw; . ## diffname port/devmnt.c 1990/12041 ## diff -e /n/bootesdump/1990/1127/sys/src/9/mips/devmnt.c /n/bootesdump/1990/12041/sys/src/9/mips/devmnt.c 855a dumpmsg(mh->mbr); . 808a dumpmsg(mh->mbr); . 781a dumpmsg(mh->mbr); . 779a mh->mbr->n = n; . 667a /* * print out first few bytes of the message */ dumpmsg(Mntbuf *mb) { int i; char *x; x = mb->buf; for(i = 0; i < mb->n; i++) print("%.2ux ", *x++); print("\n"); } . 39a int n; . ## diffname port/devmnt.c 1990/1210 ## diff -e /n/bootesdump/1990/1210/sys/src/9/mips/devmnt.c /n/bootesdump/1990/1210/sys/src/9/port/devmnt.c 874d 826d 798d 795d 669,682d 40d ## diffname port/devmnt.c 1990/1214 ## diff -e /n/bootesdump/1990/1210/sys/src/9/port/devmnt.c /n/bootesdump/1990/1214/sys/src/9/port/devmnt.c 867a USED(qlocked); . 841a USED(qlocked); . 836a USED(qlocked); . 799a USED(qlocked); . 787a USED(qlocked); . 770a USED(qlocked); . ## diffname port/devmnt.c 1990/1220 ## diff -e /n/bootesdump/1990/1214/sys/src/9/port/devmnt.c /n/bootesdump/1990/1220/sys/src/9/port/devmnt.c 877c void mntdump(void) . ## diffname port/devmnt.c 1991/0117 ## diff -e /n/bootesdump/1990/1220/sys/src/9/port/devmnt.c /n/bootesdump/1991/0117/sys/src/9/port/devmnt.c 816c goto FreeRead; . 811a FreeRead: mbfree(mh->mbr); mh->mbr = 0; . ## diffname port/devmnt.c 1991/0212 ## diff -e /n/bootesdump/1991/0117/sys/src/9/port/devmnt.c /n/bootesdump/1991/0212/sys/src/9/port/devmnt.c 694c if(devchar[q->msg->type]!='3' && devchar[q->msg->type]!='H') . 691c * Bit3 and Hotrod do their own multiplexing. (Well, the file server does.) . ## diffname port/devmnt.c 1991/0220 ## diff -e /n/bootesdump/1991/0212/sys/src/9/port/devmnt.c /n/bootesdump/1991/0220/sys/src/9/port/devmnt.c 39c char buf[BUFSIZE+BITROUND]; /* BUG */ . 34c #define BITROUND 256 #define BUFSIZE (MAXFDATA+MAXMSG) . ## diffname port/devmnt.c 1991/0306 ## diff -e /n/bootesdump/1991/0220/sys/src/9/port/devmnt.c /n/bootesdump/1991/0306/sys/src/9/port/devmnt.c 712a poperror(); /* 3 */ . 710a if(waserror()){ /* 3 */ mntflush(m, mh); nexterror(); } . ## diffname port/devmnt.c 1991/0315 ## diff -e /n/bootesdump/1991/0306/sys/src/9/port/devmnt.c /n/bootesdump/1991/0315/sys/src/9/port/devmnt.c 788d ## diffname port/devmnt.c 1991/0318 ## diff -e /n/bootesdump/1991/0315/sys/src/9/port/devmnt.c /n/bootesdump/1991/0318/sys/src/9/port/devmnt.c 877c memmove(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); . 827c memmove(&w->rhdr, &mh->rhdr, sizeof mh->rhdr); . 751c memmove(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); . 591c memmove(mh->thdr.stat, dp, DIRLEN); . 406c memmove(dp, mh->rhdr.stat, DIRLEN); . 311c memmove(mh->thdr.uname, u->p->pgrp->user, NAMELEN); . ## diffname port/devmnt.c 1991/0411 ## diff -e /n/bootesdump/1991/0318/sys/src/9/port/devmnt.c /n/bootesdump/1991/0411/sys/src/9/port/devmnt.c 785c n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0); . 770c if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){ . 716c n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0); . 703c if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){ . 568c return mntreadwrite(c, buf, n, Twrite, offset); . 566c mntwrite(Chan *c, void *buf, long n, ulong offset) . 551c n = mntreadwrite(c, buf, n, Tread, offset); . 546c mntread(Chan *c, void *buf, long n, ulong offset) . 516d 511c long nt, nr, count; . 507c mntreadwrite(Chan *c, void *vbuf, long n, int type, ulong offset) . ## diffname port/devmnt.c 1991/0414 ## diff -e /n/bootesdump/1991/0411/sys/src/9/port/devmnt.c /n/bootesdump/1991/0414/sys/src/9/port/devmnt.c 390a Chan * mntclwalk(Chan *c, char *name) { Mnt *m; Mnthdr *mh; Chan *nc; nc = newchan(); m = mntdev(c->dev, 0); mh = mhalloc(); mh->thdr.type = Tclwalk; mh->thdr.fid = c->fid; mh->thdr.newfid = nc->fid; strcpy(mh->thdr.name, name); if(waserror()){ /* BUG: can check type of error? */ freechan(nc); nc = 0; goto Out; } mntxmit(m, mh); nc->qid = mh->rhdr.qid; poperror(); Out: mhfree(mh); return nc; } . ## diffname port/devmnt.c 1991/0421 ## diff -e /n/bootesdump/1991/0414/sys/src/9/port/devmnt.c /n/bootesdump/1991/0421/sys/src/9/port/devmnt.c 609c m = mntdev(c, 0); . 543c m = mntdev(c, 0); . 501c m = mntdev(c, 0); . 473c m = mntdev(c, 0); . 448c m = mntdev(c, 0); . 424c m = mntdev(c, 0); . 411a print("mntclwalk(%d %lux)->%d %lux\n", c->type, c->qid.path, nc->type, nc->qid.path); . 405a print("mntclwalk(%d %lux) failed\n", c->type, c->qid.path); . 399c m = mntdev(c, 0); . 374c m = mntdev(c, 0); . 355a nc->aux = c->aux; nc->mntindex = c->mntindex; . 339c m = mntdev(c, 0); . 279a c->mntindex = m-mnt; . 197,202c m = &mnt[c->mntindex]; if(m->mntid==c->dev && m->q!=0) return m; . 192c mntdev(Chan *c, int noerr) . ## diffname port/devmnt.c 1991/0423 ## diff -e /n/bootesdump/1991/0421/sys/src/9/port/devmnt.c /n/bootesdump/1991/0423/sys/src/9/port/devmnt.c 415a nc->qid = mh->rhdr.qid; incref(m); . 412,414c if(mh->rhdr.fid == mh->thdr.fid) errors("directory entry not found"); . 405,410d 398a nc->type = c->type; nc->dev = c->dev; nc->qid = c->qid; nc->mode = c->mode; nc->flag = c->flag; nc->offset = c->offset; nc->mnt = c->mnt; nc->aux = c->aux; nc->mchan = c->mchan; nc->mqid = c->qid; . 397a if(waserror()){ /* BUG: can check type of error? */ freechan(nc); nc = 0; goto Out; } . 201a print("mntdev shutdown %d %d %d %lux\n", c->dev, c->mntindex, m->mntid, m->q); . ## diffname port/devmnt.c 1991/0425 ## diff -e /n/bootesdump/1991/0423/sys/src/9/port/devmnt.c /n/bootesdump/1991/0425/sys/src/9/port/devmnt.c 786a #endif . 782a #ifdef PHILW_HACK . 426,428c if(mh->rhdr.fid == mh->thdr.fid){ /* * just free the chan, the other side has * already clunked */ freechan(nc); nc = 0; } else { /* * it worked, keep the channel */ nc->qid = mh->rhdr.qid; incref(m); } . 423,424d 415a mh = 0; if(waserror()){ close(nc); if(mh) mhfree(mh); return 0; } . 400,404d ## diffname port/devmnt.c 1991/0426 ## diff -e /n/bootesdump/1991/0425/sys/src/9/port/devmnt.c /n/bootesdump/1991/0426/sys/src/9/port/devmnt.c 799d 794,795c if(mh->rhdr.fid!=mh->thdr.fid && mh->thdr.type!=Tclwalk){ . 439a nc->type = c->type; nc->dev = c->dev; nc->mode = c->mode; nc->flag = c->flag; nc->offset = c->offset; nc->mnt = c->mnt; nc->aux = c->aux; nc->mchan = c->mchan; nc->mqid = c->qid; nc->qid = mh->rhdr.qid; incref(m); poperror(); . 431,438c errors("directory entry not found"); . 428,429c * hack to indicate the most common error . 425d 401,410d ## diffname port/devmnt.c 1991/0427 ## diff -e /n/bootesdump/1991/0426/sys/src/9/port/devmnt.c /n/bootesdump/1991/0427/sys/src/9/port/devmnt.c 787c if(mh->rhdr.fid != mh->thdr.fid){ . 393,436d 355a nc->mountid = c->mountid; . ## diffname port/devmnt.c 1991/0502 ## diff -e /n/bootesdump/1991/0427/sys/src/9/port/devmnt.c /n/bootesdump/1991/0502/sys/src/9/port/devmnt.c 870a /*XXX*/ print("chan %c %d %lux %lux\n", devchar[m->q->msg->type], m->q->msg->dev, m->q->msg->qid.path, m->q->msg->stream); . 789a print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]); . 787c do{ n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0); }while(n == 0); . ## diffname port/devmnt.c 1991/0808 ## diff -e /n/bootesdump/1991/0502/sys/src/9/port/devmnt.c /n/bootesdump/1991/0808/sys/src/9/port/devmnt.c 887a mh->mbr = 0; . 848a print("%d after flush sleep %lux %lux %d %d\n", u->p->pid, mh, mh->mbr, mh->active, mh->flushing); . 847a print("%d interrupted queued sleep %lux %lux %d %d\n", u->p->pid, mh, mh->mbr, mh->active, mh->flushing); . 792c print("%d POO bad len %d %ux %lux %lux\n", u->p->pid, n, mh->mbr->buf[0], mh, mh->mbr); . 782a print("%d interrupted read %lux %lux\n", u->p->pid, mh, mh->mbr); . 684a mh->mbr = 0; } . 683c if(mh->mbr){ . 623a } . 622c if(omh->thdr.type == Tflush){ omh->flushing = 0; . 127c if(mh->active) print("mh->active\n"); if(mh->flushing) print("mh->flushing\n"); if(mh->mbr) print("mh->mbr\n"); mh->mbr = 0; . ## diffname port/devmnt.c 1991/0809 ## diff -e /n/bootesdump/1991/0808/sys/src/9/port/devmnt.c /n/bootesdump/1991/0809/sys/src/9/port/devmnt.c 858d 856d 837a if(mh->rhdr.type != Rerror) if(mh->rhdr.type != w->thdr.type+1){ print(" t%c ", devchar[m->q->msg->type]); goto FreeRead; } . 811a if(mh->rhdr.type != Rerror) if(mh->rhdr.type != mh->thdr.type+1){ print(" T%c ", devchar[m->q->msg->type]); goto FreeRead; } . 800,802c if(1){ /* BUG? IS THIS RIGHT? IGNORE AND RETRY */ print(" MR "); qlock(q); qlocked = 1; goto FreeRead; }else{ mnterrdequeue(m, mh); error(Ebadmsg); } . 790d 761a mh->mbr = 0; . ## diffname port/devmnt.c 1991/0811 ## diff -e /n/bootesdump/1991/0809/sys/src/9/port/devmnt.c /n/bootesdump/1991/0811/sys/src/9/port/devmnt.c 910a if(mh->mbr->pid != u->p->pid) print("tail\n"); . 881a } if(mh->mbr->pid != u->p->pid) print("after promotion %d\n", mh->thdr.type); . 880c mh->readreply = 0; if(q->reader == u->p){ /* i got promoted */ { Mnthdr *h; for(h=q->writer; h; h=h->next) if(h->p==u->p)print("reader and writer promotion\n"); } . 858a lock(&w->r); if(w->r.p) w->mbr->pid = w->p->pid; unlock(&w->r); . 851c print(" t%c %d %d ", devchar[m->q->msg->type], mh->rhdr.type, w->thdr.type+1); . 841a if(mh->mbr->pid != u->p->pid) print("FreeRead\n"); . 691a if(mbw->pid != u->p->pid) print("top waserror mbw\n"); . 688a if(mh->mbr->pid != u->p->pid) print("top waserror\n"); . 654a { Mnthdr *h; for(h=q->writer; h; h=h->next) if(h->p==u->p)print("reader and writer error\n"); } . 652a mh->readreply = 0; . 625a print("flush flush\n"); . 146a if(mh->pid != u->p->pid)print("mhfree pid %d\n", mh->flushing); . 130a mh->pid = u->p->pid; . 129a if(mh->readreply) print("mh->readreply\n"); . 111a if(mb->pid != u->p->pid)print("mbfree pid\n"); . 95a mb->pid = u->p->pid; . 52a int pid; . 39a int pid; . ## diffname port/devmnt.c 1991/0812 ## diff -e /n/bootesdump/1991/0811/sys/src/9/port/devmnt.c /n/bootesdump/1991/0812/sys/src/9/port/devmnt.c 932d 917,922d 901,902d 898,899c if(q->reader == u->p) /* i got promoted */ . 873,875d 864c print(" t(%d)%c %d %d ", tag, devchar[m->q->msg->type], . 859c /* * Find writer in queue */ for(w=q->writer; w; w=w->next) if(w->thdr.tag == tag) goto Inqueue; goto FreeRead; Inqueue: . 854d 851c if(tag<=0 || tag>NTAG){ . 832c print(" T(%d)%c %d %d ", tag, devchar[m->q->msg->type], mh->rhdr.type, mh->thdr.type+1); . 812,820c /* BUG? IS THIS RIGHT? IGNORE AND RETRY */ print(" MR "); qlock(q); qlocked = 1; goto FreeRead; . 703d 699d 691c Mnthdr *w, *ow, *h; . 664d 633d 239d 236,237d 234c for(i=0; itag = 0; . 157a mh->active = 0; mh->thdr.tag = 0; . 156d 153d 136c mh->thdr.tag = 1 + (incref(&mnttag) & (NTAG-1)); . 131,134d 115d 98d 87a Ref mnttag; . 54d 40d 30a int tag; /* increments per message; lock Ref while changing */ . 11a #define NTAG 16384 /* 1 <= tag <= NTAG */ . ## diffname port/devmnt.c 1991/0813 ## diff -e /n/bootesdump/1991/0812/sys/src/9/port/devmnt.c /n/bootesdump/1991/0813/sys/src/9/port/devmnt.c 935c print("(%lux %lux %d %d)", h, &h->r, h->thdr.tag, (p=h->p)? p->pid : 0); . 857c print("mail rob: '%s w(%d)%c %d %d'\n", u->p->text, tag, devchar[m->q->msg->type], . 818c print("mail rob: '%s T(%d)%c %d %d'\n", u->p->text, tag, devchar[m->q->msg->type], . 686a if(&qlocked); /* force qlocked not to be registerized */ . 169d 33d ## diffname port/devmnt.c 1991/0814 ## diff -e /n/bootesdump/1991/0813/sys/src/9/port/devmnt.c /n/bootesdump/1991/0814/sys/src/9/port/devmnt.c 857c print("mail rob: '%s xxw(%d)%c %d %d'\n", . 838c if(tag==0 || tag>=NTAG){ . 817c print("mail rob: '%s xxT(%d)%c %d %d'\n", u->p->text, . 629c mh = mhalloc(m); . 588c mh = mhalloc(m); . 522c mh = mhalloc(m); . 480c mh = mhalloc(m); . 452c mh = mhalloc(m); . 427c mh = mhalloc(m); . 403c mh = mhalloc(m); . 380c mh = mhalloc(m); . 342c mh = mhalloc(m); . 305c mh = mhalloc(m); . 240a for(i=0; inext = mq+1; --mq; mq->next = 0; . 236,238d 233c mnthdralloc.head = mh; for(i=0; iseq = 0; mh->next = mh+1; mh->prev = mh-1; } --mh; mnthdralloc.tail = mh; mh->next = 0; mnthdralloc.head->prev = 0; . 229,231d 226a for(i=0; inext = mb+1; --mb; mb->next = 0; . 223,225d 219a if(conf.nmnthdr > 512){ print("conf.nmnthdr is %d set to 512\n", conf.nmnthdr); conf.nmnthdr = 512; } . 153,154c mh->next = 0; mh->prev = mnthdralloc.tail; if(mnthdralloc.tail) mnthdralloc.tail->next = mh; else mnthdralloc.head = mh; mnthdralloc.tail = mh; . 132a mh->mbr = 0; seq = ++mh->seq; if(seq == (1<<7)){ mh->seq = 1; seq = 1; } mh->thdr.tag = (((mh-mnthdralloc.arena)<<7)|seq) & (NTAG-1); . 128,131c if(mh = mnthdralloc.head){ /* assign = */ mnthdralloc.head = mh->next; if(mnthdralloc.head) mnthdralloc.head->prev = 0; else mnthdralloc.tail = 0; . 124a int seq; . 122c mhalloc(Mnt *m) . 88d 69c Mnthdr *head; Mnthdr *tail; . 55,56c char active; char flushing; /* a Tflush has been sent */ short seq; . 12c #define NTAG 65536 /* 1 <= tag < NTAG */ . ## diffname port/devmnt.c 1991/0901 ## diff -e /n/bootesdump/1991/0814/sys/src/9/port/devmnt.c /n/bootesdump/1991/0901/sys/src/9/port/devmnt.c 968a void mntdump(void) { } . 957,967c int rpcattn(Mntrpc *r) { return r->done || r->m->rip == 0; . 952,955c dirbuf[DIRLEN-4] = devchar[c->type]; dirbuf[DIRLEN-3] = 0; dirbuf[DIRLEN-2] = c->dev; dirbuf[DIRLEN-1] = c->dev>>8; } . 950c mntdirfix(uchar *dirbuf, Chan *c) . 933,946c return m; . 926,931c Mnt * mntchk(Chan *c) { Mnt *m; m = &mntalloc.mntarena[c->mntindex]; if(m->id != c->dev) . 924a unlock(m); } . 823,923c l = &f->list; . 807,821c } void mntfree(Mntrpc *r) { Mntrpc *q; Mnt *m, *e; int i; r->bfree = 1; if(r->flushed) return; lock(&mntalloc); r->list = mntalloc.rpcfree; mntalloc.rpcfree = r; unlock(&mntalloc); } void mntqrm(Mnt *m, Mntrpc *r) { Mntrpc **l, *f; lock(m); r->done = 1; r->flushed = 0; l = &m->queue; for(f = *l; f; f = f->list) { if(f == r) { *l = r->list; break; . 796,805c for(;;) { lock(&mntalloc); if(new = mntalloc.rpcfree) { mntalloc.rpcfree = new->list; unlock(&mntalloc); new->done = 0; new->bfree = 0; return new; } unlock(&mntalloc); resrcwait("no mount buffers"); . 785,794c Mntrpc * mntralloc(void) { Mntrpc *new; . 771,783c (*devtab[m->c->type].write)(m->c, r->flush, n, 0); poperror(); lock(m); if(!r->done) r->flushed = 1; unlock(m); return 1; } . 764,769c r->flushtag++; if((r->flushtag-r->flushbase) == Flushspace) r->flushtag -= Flushspace; flush.type = Tflush; flush.tag = r->flushtag; flush.oldtag = r->request.tag; n = convS2M(&flush, r->flush); if(waserror()) { if(strcmp(u->error, errstrtab[Eintr]) == 0) return 1; mntqrm(m, r); return 0; . 759,762c int mntflush(Mnt *m, Mntrpc *r) { Fcall flush; int n; . 746,757c } . 741,744d 736,739c dispatch: if(q != r) { /* Completed someone else */ dp = q->rpc; q->rpc = r->rpc; r->rpc = dp; memmove(&q->reply, &r->reply, sizeof(Fcall)); wakeup(&q->r); . 724,734c unlock(m); return; . 721,722c if(q->flushtag == r->reply.tag) { *l = q->list; q->flushed = 0; done = q->done; q->done = 1; unlock(m); if(done == 0) { r->reply.type = Rerror; strcpy(r->reply.ename, errstrtab[Eintr]); goto dispatch; } if(q->bfree) mntfree(q); return; } l = &q->list; . 713,719c lock(m); l = &m->queue; for(q = *l; q; q = q->list) { if(q->request.tag == r->reply.tag) { if(q->flushed == 0) *l = q->list; q->done = 1; unlock(m); goto dispatch; . 707,711c Mntrpc **l, *q; int done; char *dp; . 705c mountmux(Mnt *m, Mntrpc *r) . 701c Mntrpc *q; lock(m); m->rip = 0; for(q = m->queue; q; q = q->list) if(q->done == 0) { lock(&q->r); if(q->r.p) { unlock(&q->r); unlock(m); wakeup(&q->r); return; } unlock(&q->r); } unlock(m); . 698,699c void mntgate(Mnt *m) . 692,695c n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); poperror(); if(n == 0) continue; if(convM2S(r->rpc, &r->reply, n) != 0) break; } . 677,690c for(;;) { if(waserror()) { if(mntflush(m, r) == 0) { if(m->mux == 0) mntgate(m); nexterror(); } continue; . 674,675c int n; . 672c mntrpcread(Mnt *m, Mntrpc *r) . 663,668c m->rip = u->p; unlock(m); while(r->done == 0) { mntrpcread(m, r); mountmux(m, r); } mntgate(m); . 657,661c /* Gate readers onto the mount point one at a time */ for(;;) { lock(m); if(m->rip == 0) break; unlock(m); if(waserror()) { if(mntflush(m, r) == 0) nexterror(); continue; } sleep(&r->r, rpcattn, r); poperror(); if(r->done) return; . 652,653c lock(m); r->m = m; r->list = m->queue; m->queue = r; unlock(m); /* Transmit a file system rpc */ n = convS2M(&r->request, r->rpc); if(waserror()) { mntqrm(m, r); nexterror(); } if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Eshortmsg); poperror(); if(m->mux) { mntrpcread(m, r); . 650c int n; . 648c mountio(Mnt *m, Mntrpc *r) . 643,646d 632,639c mountio(m, r); if(r->reply.type == Rerror) errors(r->reply.ename); if(r->reply.type != r->request.type+1) { print("devmnt: mismatched reply T%d R%d tags req %d fls %d rep %d\n", r->request.type, r->reply.type, r->request.tag, r->flushtag, r->reply.tag); errors("protocol error"); . 630c mountrpc(Mnt *m, Mntrpc *r) . 626a mntfree(r); return cnt; . 621,625c r->request.type = type; r->request.fid = c->fid; r->request.offset = offset; uba = buf; for(cnt = 0; n; n -= nr) { r->request.data = uba; r->request.count = limit(n, MAXFDATA); mountrpc(m, r); nr = r->reply.count; if(type == Tread) memmove(uba, r->reply.data, nr); r->request.offset += nr; uba += nr; cnt += nr; if(nr != r->request.count) break; } . 615,618c r = mntralloc(); m = mntchk(c); if(waserror()) { mntfree(r); . 613c Mntrpc *r; ulong cnt, nr; char *uba; . 606,611d 603,604c long mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) . 600c return mntrdwr(Twrite, c, buf, n, offset); . 583,593c n = mntrdwr(Tread, c, buf, n, offset); if(c->qid.path & CHDIR) for(p = (uchar*)buf, e = &p[n]; p < e; p += DIRLEN) mntdirfix(p, c); . 580,581c uchar *p, *e; . 574c mntfree(r); . 555,572c r->request.type = Twstat; r->request.fid = c->fid; memmove(r->request.stat, dp, DIRLEN); mountrpc(m, r); . 547,552c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 543,545c Mntrpc *r; . 541a mntclunk(c, Tremove); } void mntwstat(Chan *c, char *dp) { . 539,540c void mntremove(Chan *c) . 507,530c r->request.type = t; r->request.fid = c->fid; mountrpc(m, r); nexterror(); . 503,505c Mntrpc *r, *n, *q; m = mntchk(c); r = mntralloc(); if(waserror()){ mntfree(r); if(decref(m) == 0) { for(q = m->queue; q; q = r) { r = q->list; q->flushed = 0; mntfree(q); } m->id = 0; close(m->c); lock(&mntalloc); m->list = mntalloc.mntfree; mntalloc.mntfree = m; unlock(&mntalloc); } return; } . 496c poperror(); mntfree(r); . 485,493c r->request.type = Tcreate; r->request.fid = c->fid; r->request.mode = omode; r->request.perm = perm; strncpy(r->request.name, name, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; . 479,482c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 477c Mntrpc *r; . 469a poperror(); mntfree(r); . 460,466c r->request.type = Topen; r->request.fid = c->fid; r->request.mode = omode; mountrpc(m, r); c->qid = r->reply.qid; . 454,457c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 452c Mntrpc *r; . 445a mntfree(r); . 436,444c r->request.type = Tstat; r->request.fid = c->fid; mountrpc(m, r); memmove(dp, r->reply.stat, DIRLEN); mntdirfix((uchar*)dp, c); . 430,433c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 428c Mntrpc *r; . 419,421c mntfree(r); return 1; . 416,417c r->request.type = Twalk; r->request.fid = c->fid; strncpy(r->request.name, name, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; . 406,414c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); return 0; . 403,404c Mntrpc *r; . 395a poperror(); mntfree(r); . 391,394d 388d 375,378c r->request.type = Tclone; r->request.fid = c->fid; r->request.newfid = nc->fid; mountrpc(m, r); . 372c mntfree(r); if(alloc) close(nc); . 369,370d 363,367c alloc = 1; . 360,361c m = mntchk(c); r = mntralloc(); if(nc == 0) { . 357,358c Mntrpc *r; int alloc = 0; . 349a mntfree(r); . 348d 339,346c r->request.type = Tattach; r->request.fid = c->fid; memmove(r->request.uname, u->p->pgrp->user, NAMELEN); strncpy(r->request.aname, spec, NAMELEN); strncpy(r->request.auth, auth, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; c->mchan = m->c; . 335c mntfree(r); . 331,333c Chan * mattach(Mnt *m, char *spec, char *auth) { Chan *c; Mntrpc *r; r = mntralloc(); c = devattach('M', spec); c->dev = m->id; c->mntindex = m-mntalloc.mntarena; . 313,329c return mattach(m, bogus.spec, bogus.auth); } . 304,311d 302a m->queue = 0; m->rip = 0; m->c = bogus.chan; switch(devchar[m->c->type]) { case 'H': /* Hotrod */ case '3': /* BIT3 */ m->mux = 1; break; default: m->mux = 0; } incref(m->c); . 299,301c lock(&mntalloc); if(mntalloc.mntfree == 0) { unlock(&mntalloc); error(Enomntdev); } m = mntalloc.mntfree; mntalloc.mntfree = m->list; m->id = mntalloc.id++; lock(m); unlock(&mntalloc); . 290,297c bogus = *((struct bogus *)muxattach); e = &mntalloc.mntarena[conf.nmntdev]; for(m = mntalloc.mntarena; m < e; m++) { if(m->c == bogus.chan && m->id) { lock(m); if(m->ref > 0 && m->id && m->c == bogus.chan) { m->ref++; unlock(m); return mattach(m, bogus.spec, bogus.auth); } unlock(m); } . 279,283c Mnt *m, *e; . 277c mntattach(char *muxattach) . 229,271d 212,227d 193,209c mntalloc.id = 1; . 190,191c re[-1].list = 0; . 156,188c tag = Tagspace; ftag = Flushtag; mntalloc.rpcfree = ialloc(conf.nmntbuf*sizeof(Mntrpc), 0); re = &mntalloc.rpcfree[conf.nmntbuf]; for(rd = mntalloc.rpcfree; rd < re; rd++) { rd->list = rd+1; rd->request.tag = tag++; rd->flushbase = ftag; rd->flushtag = ftag; ftag += Flushspace; rd->rpc = ialloc(MAXRPC, 0); . 146,154d 128,144c if(conf.nmntbuf > Flushtag) { print("devmnt: buffers limited to %d\n", Flushtag); conf.nmntbuf = Flushtag; . 122,126c mntalloc.mntarena = ialloc(conf.nmntdev*sizeof(Mnt), 0); mntalloc.mntfree = mntalloc.mntarena; me = &mntalloc.mntfree[conf.nmntdev]; for(md = mntalloc.mntfree; md < me; md++) md->list = md+1; me[-1].list = 0; . 116,120c Mnt *me, *md; Mntrpc *re, *rd; ushort tag, ftag; . 114c mntreset(void) . 82,112d 76,80c Tagspace = 1, Flushspace = 64, Flushtag = 512, }; . 74c enum . 66,72c Chan *mattach(Mnt*, char*, char*); Mntrpc *mntralloc(void); void mntfree(Mntrpc*); int rpcattn(Mntrpc*); void mountrpc(Mnt*, Mntrpc*); void mountio(Mnt*, Mntrpc*); Mnt *mntchk(Chan*); void mountmux(Mnt*, Mntrpc*); long mntrdwr(int , Chan*, void*,long , ulong); int mntflush(Mnt*, Mntrpc*); void mntqrm(Mnt*, Mntrpc*); void mntdirfix(uchar*, Chan*); void mntgate(Mnt*); void mntrpcread(Mnt*, Mntrpc*); . 51,64c #define BITBOTCH 256 #define MAXRPC (MAXFDATA+MAXMSG+BITBOTCH) #define limit(n, max) (n > max ? max : n) . 48,49c Mnt *mntfree; Mnt *mntarena; Mntrpc *rpcfree; int id; }mntalloc; . 41,46d 36,39c struct Mntalloc . 28,33c Ref; /* Count of attached channels */ Chan *c; /* Channel to file service */ Proc *rip; /* Reader in progress */ Mntrpc *queue; /* Queue of pending requests on this channel */ int id; /* Multiplexor id for channel check */ Mnt *list; /* Free list */ char mux; /* Set if the device aleady does the multiplexing */ . 26c struct Mnt . 20,23c Mntrpc *list; /* Free/pending list */ Fcall request; /* Outgoing file system protocol message */ Fcall reply; /* Incoming reply */ Mnt *m; /* Mount device during rpc */ Rendez r; /* Place to hang out */ char *rpc; /* I/O Data buffer */ char done; /* Rpc completed */ char bfree; /* Buffer may be freed after flush */ char flushed; /* Flush was sent */ ushort flushtag; /* Tag to send flush on */ ushort flushbase; /* Base tag of flush window for this buffer */ char flush[MAXMSG]; /* Somewhere to build flush */ . 14,18c struct Mntrpc . 12c typedef struct Mntrpc Mntrpc; typedef struct Mnt Mnt; . 9d 7d ## diffname port/devmnt.c 1991/0904 ## diff -e /n/bootesdump/1991/0901/sys/src/9/port/devmnt.c /n/bootesdump/1991/0904/sys/src/9/port/devmnt.c 732a for(i=0; imsg) continue; p = q->reader; print("q rdr %d wrtr ", p? p->pid : 0); for(h=q->writer; h; h=h->next) print("(%lux %lux %d %d)", h, &h->r, h->thdr.tag, (p=h->p)? p->pid : 0); print("\n"); } } . 731c int i; MntQ *q; Mnthdr *h; Proc *p; . 714,728d 710c } /* * Copy out on read */ if(mh->thdr.type == Tread){ if(mh->rhdr.count > mh->thdr.count) error(Ebadcnt); memmove(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); } mbfree(mh->mbr); mh->mbr = 0; mbfree(mbw); USED(qlocked); poperror(); /* 1 */ . 702,708c Respond: mqfree(q); poperror(); /* 2 */ if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); . 699,700d 697c mh->mbr = mballoc(); do{ n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0); }while(n == 0); poperror(); /* 3 */ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ /* BUG? IS THIS RIGHT? IGNORE AND RETRY */ print(" MR "); qlock(q); qlocked = 1; goto FreeRead; } /* * Response might not be mine */ USED(qlocked); qlock(q); qlocked = 1; tag = mh->rhdr.tag; if(tag == mh->thdr.tag){ /* it's mine */ if(mh->rhdr.type != Rerror) if(mh->rhdr.type != mh->thdr.type+1){ print("mail rob: '%s xxT(%d)%c %d %d'\n", u->p->text, tag, devchar[m->q->msg->type], mh->rhdr.type, mh->thdr.type+1); goto FreeRead; } q->reader = 0; if(w = q->writer){ /* advance a writer to reader */ mntwunlink(q, w); q->reader = w->p; w->readreply = 1; wakeup(&w->r); } mh->active = 0; USED(qlocked); qunlock(q); qlocked = 0; goto Respond; } /* * Hand response to correct recipient */ if(tag==0 || tag>=NTAG){ print("unknown tag %d\n", tag); FreeRead: mbfree(mh->mbr); mh->mbr = 0; goto Read; } /* * Find writer in queue */ for(w=q->writer; w; w=w->next) if(w->thdr.tag == tag) goto Inqueue; goto FreeRead; Inqueue: if(w->flushing || !w->active) /* nothing to do; mntflush will clean up */ goto FreeRead; if(mh->rhdr.type != Rerror) if(mh->rhdr.type != w->thdr.type+1){ print("mail rob: '%s xxw(%d)%c %d %d'\n", u->p->text, tag, devchar[m->q->msg->type], mh->rhdr.type, w->thdr.type+1); goto FreeRead; } w->mbr = mh->mbr; mh->mbr = 0; memmove(&w->rhdr, &mh->rhdr, sizeof mh->rhdr); mntwunlink(q, w); w->readreply = 1; wakeup(&w->r); goto Read; }else{ mh->p = u->p; /* put self in queue */ mh->next = q->writer; mh->prev = 0; if(q->writer) q->writer->prev = mh; q->writer = mh; qunlock(q); qlocked = 0; if(waserror()){ /* interrupted sleep */ mnterrdequeue(m, mh); nexterror(); } sleep(&mh->r, mntreadreply, mh); poperror(); USED(qlocked); qlock(q); qlocked = 1; mh->readreply = 0; if(q->reader == u->p) /* i got promoted */ goto Read; mh->active = 0; USED(qlocked); qunlock(q); qlocked = 0; goto Respond; . 672,695c Normal: #endif incref(q); qlock(q); qlocked = 1; if(waserror()){ /* 2 */ if(qlocked) qunlock(q); mqfree(q); nexterror(); } mh->readreply = 0; mh->active = 1; if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){ print("short write in mntxmit\n"); error(Eshortmsg); } if(q->reader == 0){ /* i will read */ q->reader = u->p; Read: USED(qlocked); qunlock(q); qlocked = 0; if(waserror()){ /* 3 */ mnterrdequeue(m, mh); nexterror(); . 665,670c /* * Copy out on read */ if(mh->thdr.type == Tread) memmove(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); mbfree(mh->mbr); mh->mbr = 0; mbfree(mbw); poperror(); /* 1 */ return; . 663c if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); error(Eshutdown); } if(mh->rhdr.type != mh->thdr.type+1){ print("type mismatch %d %d\n", mh->rhdr.type, mh->thdr.type+1); error(Ebadmsg); } if(mh->rhdr.fid != mh->thdr.fid){ print("fid mismatch %d %d type %d\n", mh->rhdr.fid, mh->thdr.fid, mh->rhdr.type); error(Ebadmsg); } . 646,661c /* * Various checks */ if(mh->rhdr.tag != mh->thdr.tag){ print("tag mismatch %d %d\n", mh->rhdr.tag, mh->thdr.tag); error(Ebadmsg); . 637,644d 616,635c if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); error(Ebadmsg); . 614c /* * Read response */ if(waserror()){ /* 3 */ mntflush(m, mh); nexterror(); } mh->mbr = mballoc(); n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE, 0); poperror(); /* 3 */ mqfree(q); poperror(); /* 2 */ . 612a if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){ print("short write in mntxmit\n"); error(Eshortmsg); } . 605,611c incref(q); if(waserror()){ /* 2 */ mqfree(q); nexterror(); . 602,603c n = convS2M(&mh->thdr, mbw->buf); q = m->q; if(q == 0) error(Eshutdown); #ifdef BIT3 /* * Bit3 and Hotrod do their own multiplexing. (Well, the file server does.) * The code is different enough that it's broken out separately here. */ if(devchar[q->msg->type]!='3' && devchar[q->msg->type]!='H') goto Normal; . 585,600c mbfree(mbw); nexterror(); . 575,583c if(&qlocked); /* force qlocked not to be registerized */ mh->mbr = 0; mbw = mballoc(); if(waserror()){ /* 1 */ if(mh->mbr){ mbfree(mh->mbr); mh->mbr = 0; . 571,573c ulong n; Mntbuf *mbw; Mnthdr *w, *ow, *h; MntQ *q; int qlocked, tag, written; . 569c mntxmit(Mnt *m, Mnthdr *mh) . 550,565c return ((Mnthdr *)a)->readreply; . 547,548c int mntreadreply(void *a) . 538,544c }else mntwunlink(q, mh); qunlock(q); mntflush(m, mh); . 529,536c mh->flushing = 1; q = m->q; qlock(q); mh->readreply = 0; /* take self from queue if necessary */ if(q->reader == u->p){ /* advance a writer to reader */ w = q->writer; if(w){ mntwunlink(q, w); q->reader = w->p; wakeup(&w->r); }else{ q->reader = 0; q->writer = 0; . 527c Mnthdr *w; MntQ *q; . 525c mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */ . 514,521c mh->thdr.type = Tflush; mh->thdr.oldtag = omh->thdr.tag; mntxmit(m, mh); omh->flushing = 0; mhfree(mh); poperror(); . 498,512c mh = mhalloc(m); if(waserror()){ omh->flushing = 0; mhfree(mh); return; /* no more errors please */ . 477,494c if(omh->thdr.type == Tflush){ omh->flushing = 0; . 475c Mnthdr *mh; . 473c mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ . 471a /* * m->q is unlocked. Send Tflush message to flush omh->tag. * Cut off all errors. Caller will free omh */ . 463,468c if(w->next) w->next->prev = w->prev; if(w->prev) w->prev->next = w->next; else{ q->writer = w->next; if(q->writer) q->writer->prev = 0; . 461c mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */ . 456,457d 438,454c mh->thdr.type = Twstat; mh->thdr.fid = c->fid; memmove(mh->thdr.stat, dp, DIRLEN); mntxmit(m, mh); mhfree(mh); . 432,435c m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); . 428,430c Mnthdr *mh; . 426a mntclunk(c, Tremove); } void mntwstat(Chan *c, char *dp) { . 424,425c void mntremove(Chan *c) . 421c return mntreadwrite(c, buf, n, Twrite, offset); . 410,414c n = mntreadwrite(c, buf, n, Tread, offset); if(c->qid.path & CHDIR){ b = (uchar*)buf; for(i=n-DIRLEN; i>=0; i-=DIRLEN){ b[DIRLEN-4] = devchar[c->type]; b[DIRLEN-3] = 0; b[DIRLEN-2] = c->dev; b[DIRLEN-1] = c->dev>>8; b += DIRLEN; } } . 408c long i; uchar *b; . 402c return count; . 397,400c mh->thdr.type = type; mh->thdr.fid = c->fid; Loop: nt = n; if(nt > MAXFDATA) nt = MAXFDATA; mh->thdr.offset = offset; mh->thdr.count = nt; mh->thdr.data = buf; mntxmit(m, mh); nr = mh->rhdr.count; offset += nr; count += nr; buf += nr; n -= nr; if(n && nr==nt) goto Loop; mhfree(mh); . 391,394c buf = vbuf; count = 0; m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); . 389c Mnthdr *mh; long nt, nr, count; char *buf; . 382,387d 379,380c long mntreadwrite(Chan *c, void *vbuf, long n, int type, ulong offset) . 367,370c m = mntdev(c, 0); mh = mhalloc(m); mh->thdr.type = t; mh->thdr.fid = c->fid; waserr = 0; if(waserror()) /* gotta clean up as if there wasn't */ waserr = 1; else mntxmit(m, mh); mhfree(mh); if(c == m->mntpt) m->mntpt = 0; lock(m); if(--m->ref == 0){ /* BUG: need to hang up all pending i/o */ q = m->q; m->q = 0; m->mntid = 0; unlock(m); /* mqfree can take time */ mqfree(q); }else unlock(m); if(waserr) nexterror(); poperror(); . 345,365c Mnthdr *mh; MntQ *q; int waserr; . 337,338c c->qid = mh->rhdr.qid; . 327,334c mh->thdr.type = Tcreate; mh->thdr.fid = c->fid; strcpy(mh->thdr.name, name); mh->thdr.mode = omode; mh->thdr.perm = perm; mntxmit(m, mh); c->qid = mh->rhdr.qid; mhfree(mh); poperror(); . 321,324c m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); . 319c Mnthdr *mh; . 310,311d 301,306c mh->thdr.type = Topen; mh->thdr.fid = c->fid; mh->thdr.mode = omode; mntxmit(m, mh); c->qid = mh->rhdr.qid; mhfree(mh); poperror(); . 295,298c m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); . 293c Mnthdr *mh; . 286d 279,284c mh->thdr.type = Tstat; mh->thdr.fid = c->fid; mntxmit(m, mh); memmove(dp, mh->rhdr.stat, DIRLEN); dp[DIRLEN-4] = devchar[c->type]; dp[DIRLEN-3] = 0; dp[DIRLEN-2] = c->dev; dp[DIRLEN-1] = c->dev>>8; mhfree(mh); . 273,276c m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); . 271c Mnthdr *mh; . 263,264c Out: mhfree(mh); return found; . 255,261c mntxmit(m, mh); c->qid = mh->rhdr.qid; . 249,253c found = 1; m = mntdev(c, 0); mh = mhalloc(m); mh->thdr.type = Twalk; mh->thdr.fid = c->fid; strcpy(mh->thdr.name, name); if(waserror()){ /* BUG: can check type of error? */ found = 0; goto Out; . 247c Mnthdr *mh; int found; . 239c if(new) poperror(); incref(m); . 236,237c mhfree(mh); . 233a nc->mntindex = c->mntindex; . 219,224c mh->thdr.type = Tclone; mh->thdr.fid = c->fid; mh->thdr.newfid = nc->fid; mntxmit(m, mh); . 214,216c mhfree(mh); . 212a m = mntdev(c, 0); mh = mhalloc(m); . 211c new = 1; if(waserror()){ close(nc); nexterror(); } . 207,209c new = 0; if(nc == 0){ . 204,205c Mnthdr *mh; int new; . 196d 194a mhfree(mh); . 185,193c mh->thdr.type = Tattach; mh->thdr.fid = c->fid; memmove(mh->thdr.uname, u->p->pgrp->user, NAMELEN); strcpy(mh->thdr.aname, bogus.spec); strcpy(mh->thdr.auth, bogus.auth); mntxmit(m, mh); c->qid = mh->rhdr.qid; c->mchan = m->q->msg; . 181c mhfree(mh); . 168,179c out: qunlock(&mntqalloc); mh = mhalloc(m); . 165,166c /* * Look for queue to same msg channel */ q = mntqalloc.arena; qlock(&mntqalloc); for(i=0; imsg==cm){ lock(q); if(q->ref && q->msg==cm){ m->q = q; q->ref++; unlock(q); goto out; } unlock(q); } m->q = mqalloc(cm); . 163a lock(&mntid); m->mntid = ++mntid.id; unlock(&mntid); c = devattach('M', bogus.spec); c->dev = m->mntid; c->mntindex = m-mnt; m->mntpt = c; cm = bogus.chan; . 162c error(Enomntdev); Found: m->ref = 1; . 154,160c m = mnt; for(i=0; iref == 0) goto Found; unlock(m); . 126,152c bogus = *((struct bogus *)crud); . 119c int i; Mnt *m, *mm; Mnthdr *mh; MntQ *q; Chan *c, *cm; . 117c mntattach(char *crud) . 111a mntreset(void) { int i; Mntbuf *mb; Mnthdr *mh; MntQ *mq; if(conf.nmnthdr > 512){ print("conf.nmnthdr is %d set to 512\n", conf.nmnthdr); conf.nmnthdr = 512; } mnt = ialloc(conf.nmntdev*sizeof(Mnt), 0); mb = ialloc(conf.nmntbuf*sizeof(Mntbuf), 0); mntbufalloc.free = mb; for(i=0; inext = mb+1; --mb; mb->next = 0; mh = ialloc(conf.nmnthdr*sizeof(Mnthdr), 0); mnthdralloc.arena = mh; mnthdralloc.head = mh; for(i=0; iseq = 0; mh->next = mh+1; mh->prev = mh-1; } --mh; mnthdralloc.tail = mh; mh->next = 0; mnthdralloc.head->prev = 0; mq = ialloc(conf.nmntdev*sizeof(MntQ), 0); mntqalloc.arena = mq; mntqalloc.free = mq; for(i=0; inext = mq+1; --mq; mq->next = 0; } void . 110a Mnt* mntdev(Chan *c, int noerr) { Mnt *m; int i; m = &mnt[c->mntindex]; if(m->mntid==c->dev && m->q!=0) return m; if(noerr) return 0; print("mntdev shutdown %d %d %d %lux\n", c->dev, c->mntindex, m->mntid, m->q); error(Eshutdown); } . 108c void mqfree(MntQ *mq) { Chan *msg = 0; lock(mq); if(--mq->ref == 0){ msg = mq->msg; mq->msg = 0; lock(&mntqalloc); mq->next = mntqalloc.free; mntqalloc.free = mq; unlock(&mntqalloc); } unlock(mq); if(msg) /* after locks are down */ close(msg); . 106c panic("no mntqs\n"); /* there MUST be enough */ } . 94,104c void mhfree(Mnthdr *mh) { if(mh->flushing) return; lock(&mnthdralloc); mh->active = 0; mh->thdr.tag = 0; mh->next = 0; mh->prev = mnthdralloc.tail; if(mnthdralloc.tail) mnthdralloc.tail->next = mh; else mnthdralloc.head = mh; mnthdralloc.tail = mh; unlock(&mnthdralloc); } MntQ* mqalloc(Chan *msg) /* mntqalloc is qlocked */ { MntQ *q; if(q = mntqalloc.free){ /* assign = */ mntqalloc.free = q->next; lock(q); q->ref = 1; q->msg = msg; unlock(q); incref(msg); q->writer = 0; q->reader = 0; return q; . 92a unlock(&mnthdralloc); print("no mnthdrs\n"); if(u == 0) panic("mhalloc"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); goto loop; } . 89,91c loop: lock(&mnthdralloc); if(mh = mnthdralloc.head){ /* assign = */ mnthdralloc.head = mh->next; if(mnthdralloc.head) mnthdralloc.head->prev = 0; else mnthdralloc.tail = 0; unlock(&mnthdralloc); mh->mbr = 0; seq = ++mh->seq; if(seq == (1<<7)){ mh->seq = 1; seq = 1; } mh->thdr.tag = (((mh-mnthdralloc.arena)<<7)|seq) & (NTAG-1); return mh; . 82,87c Mnthdr* mhalloc(Mnt *m) { Mnthdr *mh; int seq; . 78,80c lock(&mntbufalloc); mb->next = mntbufalloc.free; mntbufalloc.free = mb; unlock(&mntbufalloc); } . 76c mbfree(Mntbuf *mb) . 74a struct { Lock; long id; }mntid; Mnt *mnt; void mntxmit(Mnt*, Mnthdr*); Mntbuf* mballoc(void) { Mntbuf *mb; loop: lock(&mntbufalloc); if(mb = mntbufalloc.free){ /* assign = */ mntbufalloc.free = mb->next; unlock(&mntbufalloc); return mb; } unlock(&mntbufalloc); print("no mntbufs\n"); if(u == 0) panic("mballoc"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); goto loop; } . 70,73c Lock; QLock; MntQ *arena; MntQ *free; }mntqalloc; . 68c struct . 53,66c struct { Lock; Mnthdr *arena; Mnthdr *head; Mnthdr *tail; }mnthdralloc; . 49,51c struct Mnthdr { Mnthdr *next; /* in free list or writers list */ Mnthdr *prev; /* in writers list only */ char active; char flushing; /* a Tflush has been sent */ short seq; Fcall thdr; Fcall rhdr; Rendez r; Proc *p; Mntbuf *mbr; int readreply; /* true if we are reader or our reply has come */ }; . 43,47c Mntbuf *free; }mntbufalloc; . 41a Mntbuf *next; char buf[BUFSIZE+BITROUND]; /* BUG */ }; struct { . 40c #define BITROUND 256 #define BUFSIZE (MAXFDATA+MAXMSG) typedef struct Mntbuf Mntbuf; struct Mntbuf . 31,37c Ref; QLock; /* for access */ MntQ *next; /* for allocation */ Chan *msg; /* for reading and writing messages */ Proc *reader; /* process reading response */ Mnthdr *writer; /* queue of headers of written messages */ . 29c struct MntQ . 15,26c Ref; /* for number of chans, incl. mntpt but not msg */ ulong mntid; /* serial # */ Chan *mntpt; /* channel in user's name space */ MntQ *q; . 13c typedef struct Mnt Mnt; typedef struct Mnthdr Mnthdr; typedef struct MntQ MntQ; struct Mnt . 10,11c #define NTAG 65536 /* 1 <= tag < NTAG */ . 7a . 6a . ## diffname port/devmnt.c 1991/0910 ## diff -e /n/bootesdump/1991/0904/sys/src/9/port/devmnt.c /n/bootesdump/1991/0910/sys/src/9/port/devmnt.c 964,965c print("(%lux %lux %d)", h, &h->r, (p=h->p)? p->pid : 0); . 932a }else if(mh->rhdr.type != mh->thdr.type+1){ print("bad type %d not %d in mntxmit\n", mh->rhdr.type, mh->thdr.type+1); /*XXX*/ print("chan %c %d %lux %lux\n", devchar[m->q->msg->type], m->q->msg->dev, m->q->msg->qid.path, m->q->msg->stream); error(Ebadmsg); . 916d 885,887c print(" t%c ", devchar[m->q->msg->type]); . 873,880c w = &mnthdralloc.arena[tag]; . 866c if(tag<0 || tag>=conf.nmnthdr){ . 845,847c print(" T%c ", devchar[m->q->msg->type]); . 829,833c if(1){ /* BUG? IS THIS RIGHT? IGNORE AND RETRY */ print(" MR "); qlock(q); qlocked = 1; goto FreeRead; }else{ mnterrdequeue(m, mh); error(Ebadmsg); } . 713d 709c Mnthdr *w, *ow; . 680d 657c mh = mhalloc(); . 616c mh = mhalloc(); . 550c mh = mhalloc(); . 508c mh = mhalloc(); . 480c mh = mhalloc(); . 455c mh = mhalloc(); . 431c mh = mhalloc(); . 408c mh = mhalloc(); . 370c mh = mhalloc(); . 333c mh = mhalloc(); . 265,268d 262a for(i=0; inext = mnthdralloc.free; mnthdralloc.free = mh; . 161d 138,143c unlock(&mnthdralloc); . 130,136c if(mh = mnthdralloc.free){ /* assign = */ mnthdralloc.free = mh->next; if(mh->active) print("mh->active\n"); if(mh->flushing) print("mh->flushing\n"); if(mh->mbr) print("mh->mbr\n"); . 126d 123c mhalloc(void) . 70,71c Mnthdr *free; . 55,57c short active; short flushing; /* a Tflush has been sent */ . 12,13d ## diffname port/devmnt.c 1991/0911 ## diff -e /n/bootesdump/1991/0910/sys/src/9/port/devmnt.c /n/bootesdump/1991/0911/sys/src/9/port/devmnt.c 936a . 935a print("rpcfree 0x%lux\n", mntalloc.rpcfree); re = &mntalloc.rpcarena[conf.nmntbuf]; for(r = mntalloc.rpcarena; r < re; r++) print("%.8lux %.8lux T%d R%d tags req %d fls %d rep %d d %d b %d f %d\n", r, r->list, r->request.type, r->reply.type, r->request.tag, r->flushtag, r->reply.tag, r->done, r->bfree, r->flushed); . 930,934c print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n", m->id, m->mux, m->queue, m->rip, m->rip ? m->rip->pid : 0, m->rip ? m->rip->text : "no"); . 926,928c me = &mntalloc.mntarena[conf.nmntdev]; for(m = mntalloc.mntarena; m < me; m++) { if(m->ref == 0) . 921,924c Mnt *me, *m; Mntrpc *re, *r; . 918a mntdirfix(uchar *dirbuf, Chan *c) { dirbuf[DIRLEN-4] = devchar[c->type]; dirbuf[DIRLEN-3] = 0; dirbuf[DIRLEN-2] = c->dev; dirbuf[DIRLEN-1] = c->dev>>8; } int rpcattn(Mntrpc *r) { return r->done || r->m->rip == 0; } void . 896,915c return m; . 889,894c Mnt * mntchk(Chan *c) { Mnt *m; m = &mntalloc.mntarena[c->mntindex]; if(m->id != c->dev) . 887a unlock(m); } . 794,886c l = &f->list; . 778,792c } void mntfree(Mntrpc *r) { Mntrpc *q; Mnt *m, *e; int i; r->bfree = 1; if(r->flushed) return; lock(&mntalloc); r->list = mntalloc.rpcfree; mntalloc.rpcfree = r; unlock(&mntalloc); } void mntqrm(Mnt *m, Mntrpc *r) { Mntrpc **l, *f; lock(m); r->done = 1; r->flushed = 0; l = &m->queue; for(f = *l; f; f = f->list) { if(f == r) { *l = r->list; break; . 767,776c for(;;) { lock(&mntalloc); if(new = mntalloc.rpcfree) { mntalloc.rpcfree = new->list; unlock(&mntalloc); new->done = 0; new->bfree = 0; return new; } unlock(&mntalloc); resrcwait("no mount buffers"); . 756,765c Mntrpc * mntralloc(void) { Mntrpc *new; . 742,754c qlock(&m->c->wrl); (*devtab[m->c->type].write)(m->c, r->flush, n, 0); qunlock(&m->c->wrl); poperror(); lock(m); if(!r->done) r->flushed = 1; unlock(m); return 1; } . 735,740c flush.type = Tflush; flush.tag = r->flushtag; flush.oldtag = r->request.tag; n = convS2M(&flush, r->flush); if(waserror()) { qunlock(&m->c->wrl); if(strcmp(u->error, errstrtab[Eintr]) == 0) return 1; mntqrm(m, r); return 0; . 730,733c r->flushtag++; if((r->flushtag-r->flushbase) == Flushspace) r->flushtag -= Flushspace; . 717,728c int mntflush(Mnt *m, Mntrpc *r) { Fcall flush; int n; . 712,715c } . 707,710c dispatch: if(q != r) { /* Completed someone else */ dp = q->rpc; q->rpc = r->rpc; r->rpc = dp; memmove(&q->reply, &r->reply, sizeof(Fcall)); wakeup(&q->r); . 695,705c unlock(m); return; . 692,693c if(q->flushtag == r->reply.tag) { *l = q->list; q->flushed = 0; done = q->done; q->done = 1; unlock(m); if(done == 0) goto dispatch; if(q->bfree) mntfree(q); return; } l = &q->list; . 685,690c lock(m); l = &m->queue; for(q = *l; q; q = q->list) { if(q->request.tag == r->reply.tag) { if(q->flushed == 0) *l = q->list; q->done = 1; unlock(m); goto dispatch; . 679,683c Mntrpc **l, *q; int done; char *dp; . 677c mountmux(Mnt *m, Mntrpc *r) . 673c Mntrpc *q; lock(m); m->rip = 0; for(q = m->queue; q; q = q->list) if(q->done == 0) { lock(&q->r); if(q->r.p) { unlock(&q->r); unlock(m); wakeup(&q->r); return; } unlock(&q->r); } unlock(m); . 670,671c void mntgate(Mnt *m) . 664,667c qlock(&m->c->rdl); r->reply.type = 0; r->reply.tag = 0; n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); qunlock(&m->c->rdl); poperror(); if(n == 0) continue; if(convM2S(r->rpc, &r->reply, n) != 0) return; } . 650,662c for(;;) { if(waserror()) { qunlock(&m->c->rdl); if(mntflush(m, r) == 0) { if(m->mux == 0) mntgate(m); nexterror(); } continue; . 647,648c int n; . 645c mntrpcread(Mnt *m, Mntrpc *r) . 636,641c m->rip = u->p; unlock(m); while(r->done == 0) { mntrpcread(m, r); mountmux(m, r); } mntgate(m); . 630,634c /* Gate readers onto the mount point one at a time */ for(;;) { lock(m); if(m->rip == 0) break; unlock(m); if(waserror()) { if(mntflush(m, r) == 0) nexterror(); continue; } sleep(&r->r, rpcattn, r); poperror(); if(r->done) return; . 625,626c lock(m); r->m = m; r->list = m->queue; m->queue = r; unlock(m); /* Transmit a file system rpc */ n = convS2M(&r->request, r->rpc); if(waserror()) { qunlock(&m->c->wrl); mntqrm(m, r); nexterror(); } qlock(&m->c->wrl); if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Eshortmsg); qunlock(&m->c->wrl); poperror(); if(m->mux) { mntqrm(m, r); mntrpcread(m, r); . 623c int n; . 621c mountio(Mnt *m, Mntrpc *r) . 616,619d 605,612c r->reply.tag = 0; /* safety check */ mountio(m, r); if(r->reply.type == Rerror) errors(r->reply.ename); if(r->reply.type == Rflush) errors(errstrtab[Eintr]); if(r->reply.type != r->request.type+1) { print("devmnt: mismatched reply 0x%lux T%d R%d tags req %d fls %d rep %d\n", r, r->request.type, r->reply.type, r->request.tag, r->flushtag, r->reply.tag); errors("protocol error"); . 603c mountrpc(Mnt *m, Mntrpc *r) . 594,599c return cnt; . 588,592c m = mntchk(c); uba = buf; for(cnt = 0; n; n -= nr) { r = mntralloc(); if(waserror()) { mntfree(r); nexterror(); } r->request.type = type; r->request.fid = c->fid; r->request.offset = offset; r->request.data = uba; r->request.count = limit(n, MAXFDATA); mountrpc(m, r); nr = r->reply.count; if(type == Tread) memmove(uba, r->reply.data, nr); poperror(); mntfree(r); offset += nr; uba += nr; cnt += nr; if(nr != r->request.count) break; . 586c Mntrpc *r; ulong cnt, nr; char *uba; . 579,584d 576,577c long mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) . 573c return mntrdwr(Twrite, c, buf, n, offset); . 556,566c n = mntrdwr(Tread, c, buf, n, offset); if(c->qid.path & CHDIR) for(p = (uchar*)buf, e = &p[n]; p < e; p += DIRLEN) mntdirfix(p, c); . 553,554c uchar *p, *e; . 547c mntfree(r); . 528,545c r->request.type = Twstat; r->request.fid = c->fid; memmove(r->request.stat, dp, DIRLEN); mountrpc(m, r); . 520,525c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 516,518c Mntrpc *r; . 514a mntclunk(c, Tremove); } void mntwstat(Chan *c, char *dp) { . 512,513c void mntremove(Chan *c) . 480,503c r->request.type = t; r->request.fid = c->fid; mountrpc(m, r); nexterror(); . 476,478c Mntrpc *r, *n, *q; m = mntchk(c); r = mntralloc(); if(waserror()){ mntfree(r); if(decref(m) == 0) { for(q = m->queue; q; q = r) { r = q->list; q->flushed = 0; mntfree(q); } m->id = 0; close(m->c); lock(&mntalloc); m->list = mntalloc.mntfree; mntalloc.mntfree = m; unlock(&mntalloc); } return; } . 469c poperror(); mntfree(r); . 458,466c r->request.type = Tcreate; r->request.fid = c->fid; r->request.mode = omode; r->request.perm = perm; strncpy(r->request.name, name, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; . 452,455c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 450c Mntrpc *r; . 442a poperror(); mntfree(r); . 433,439c r->request.type = Topen; r->request.fid = c->fid; r->request.mode = omode; mountrpc(m, r); c->qid = r->reply.qid; . 427,430c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 425c Mntrpc *r; . 418a mntfree(r); . 409,417c r->request.type = Tstat; r->request.fid = c->fid; mountrpc(m, r); memmove(dp, r->reply.stat, DIRLEN); mntdirfix((uchar*)dp, c); . 403,406c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); . 401c Mntrpc *r; . 392,394c mntfree(r); return 1; . 389,390c r->request.type = Twalk; r->request.fid = c->fid; strncpy(r->request.name, name, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; . 379,387c m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); return 0; . 376,377c Mntrpc *r; . 368a poperror(); mntfree(r); . 364,367d 361d 348,351c r->request.type = Tclone; r->request.fid = c->fid; r->request.newfid = nc->fid; mountrpc(m, r); . 345c mntfree(r); if(alloc) close(nc); . 342,343d 336,340c alloc = 1; . 333,334c m = mntchk(c); r = mntralloc(); if(nc == 0) { . 330,331c Mntrpc *r; int alloc = 0; . 322a mntfree(r); . 321d 312,319c r->request.type = Tattach; r->request.fid = c->fid; memmove(r->request.uname, u->p->pgrp->user, NAMELEN); strncpy(r->request.aname, spec, NAMELEN); strncpy(r->request.auth, auth, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; c->mchan = m->c; . 308c mntfree(r); . 304,306c Chan * mattach(Mnt *m, char *spec, char *auth) { Chan *c; Mntrpc *r; r = mntralloc(); c = devattach('M', spec); c->dev = m->id; c->mntindex = m-mntalloc.mntarena; . 286,302c return mattach(m, bogus.spec, bogus.auth); } . 277,284d 275a m->queue = 0; m->rip = 0; m->c = bogus.chan; switch(devchar[m->c->type]) { case 'H': /* Hotrod */ case '3': /* BIT3 */ m->mux = 1; break; default: m->mux = 0; } incref(m->c); . 272,274c lock(&mntalloc); if(mntalloc.mntfree == 0) { unlock(&mntalloc); error(Enomntdev); } m = mntalloc.mntfree; mntalloc.mntfree = m->list; m->id = mntalloc.id++; lock(m); unlock(&mntalloc); . 263,270c bogus = *((struct bogus *)muxattach); e = &mntalloc.mntarena[conf.nmntdev]; for(m = mntalloc.mntarena; m < e; m++) { if(m->c == bogus.chan && m->id) { lock(m); if(m->ref > 0 && m->id && m->c == bogus.chan) { m->ref++; unlock(m); return mattach(m, bogus.spec, bogus.auth); } unlock(m); } . 252,256c Mnt *m, *e; . 250c mntattach(char *muxattach) . 211,244d 194,209d 175,191c mntalloc.id = 1; . 172,173c re[-1].list = 0; . 144,170c tag = Tagspace; ftag = Flushtag; mntalloc.rpcfree = ialloc(conf.nmntbuf*sizeof(Mntrpc), 0); mntalloc.rpcarena = mntalloc.rpcfree; re = &mntalloc.rpcfree[conf.nmntbuf]; for(rd = mntalloc.rpcfree; rd < re; rd++) { rd->list = rd+1; rd->request.tag = tag++; rd->flushbase = ftag; rd->flushtag = ftag; ftag += Flushspace; rd->rpc = ialloc(MAXRPC, 0); . 134,142d 123,132c if(conf.nmntbuf > Flushtag) { print("devmnt: buffers limited to %d\n", Flushtag); conf.nmntbuf = Flushtag; . 118,121c mntalloc.mntarena = ialloc(conf.nmntdev*sizeof(Mnt), 0); mntalloc.mntfree = mntalloc.mntarena; me = &mntalloc.mntfree[conf.nmntdev]; for(md = mntalloc.mntfree; md < me; md++) md->list = md+1; me[-1].list = 0; . 112,116c Mnt *me, *md; Mntrpc *re, *rd; ushort tag, ftag; . 110c mntreset(void) . 78,108d 72,76c Tagspace = 1, Flushspace = 64, Flushtag = 512, }; . 70c enum . 63,68c Chan *mattach(Mnt*, char*, char*); Mntrpc *mntralloc(void); void mntfree(Mntrpc*); int rpcattn(Mntrpc*); void mountrpc(Mnt*, Mntrpc*); void mountio(Mnt*, Mntrpc*); Mnt *mntchk(Chan*); void mountmux(Mnt*, Mntrpc*); long mntrdwr(int , Chan*, void*,long , ulong); int mntflush(Mnt*, Mntrpc*); void mntqrm(Mnt*, Mntrpc*); void mntdirfix(uchar*, Chan*); void mntgate(Mnt*); void mntrpcread(Mnt*, Mntrpc*); . 49,61c #define BITBOTCH 256 #define MAXRPC (MAXFDATA+MAXMSG+BITBOTCH) #define limit(n, max) (n > max ? max : n) . 46,47c Mnt *mntfree; Mnt *mntarena; Mntrpc *rpcfree; Mntrpc *rpcarena; int id; }mntalloc; . 39,44d 34,37c struct Mntalloc . 26,31c Ref; /* Count of attached channels */ Chan *c; /* Channel to file service */ Proc *rip; /* Reader in progress */ Mntrpc *queue; /* Queue of pending requests on this channel */ int id; /* Multiplexor id for channel check */ Mnt *list; /* Free list */ char mux; /* Set if the device aleady does the multiplexing */ . 24c struct Mnt . 18,21c Mntrpc *list; /* Free/pending list */ Fcall request; /* Outgoing file system protocol message */ Fcall reply; /* Incoming reply */ Mnt *m; /* Mount device during rpc */ Rendez r; /* Place to hang out */ char *rpc; /* I/O Data buffer */ char done; /* Rpc completed */ char bfree; /* Buffer may be freed after flush */ char flushed; /* Flush was sent */ ushort flushtag; /* Tag to send flush on */ ushort flushbase; /* Base tag of flush window for this buffer */ char flush[MAXMSG]; /* Somewhere to build flush */ . 16c struct Mntrpc . 12,14c typedef struct Mntrpc Mntrpc; typedef struct Mnt Mnt; . 9d 7d ## diffname port/devmnt.c 1991/0912 ## diff -e /n/bootesdump/1991/0911/sys/src/9/port/devmnt.c /n/bootesdump/1991/0912/sys/src/9/port/devmnt.c 474,475c r, r->request.type, r->reply.type, r->request.tag, r->flushtag, r->reply.tag); . ## diffname port/devmnt.c 1991/0918 ## diff -e /n/bootesdump/1991/0912/sys/src/9/port/devmnt.c /n/bootesdump/1991/0918/sys/src/9/port/devmnt.c 722c /* Was it closed and reused ? */ if(m->id == 0 || m->id >= c->dev) . 179c lock(&mntalloc); c->dev = mntalloc.id++; unlock(&mntalloc); . ## diffname port/devmnt.c 1991/0924 ## diff -e /n/bootesdump/1991/0918/sys/src/9/port/devmnt.c /n/bootesdump/1991/0924/sys/src/9/port/devmnt.c 367a mntfree(r); . 354d ## diffname port/devmnt.c 1991/0925 ## diff -e /n/bootesdump/1991/0924/sys/src/9/port/devmnt.c /n/bootesdump/1991/0925/sys/src/9/port/devmnt.c 499,504c else { qlock(&m->c->wrl); if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Eshortmsg); qunlock(&m->c->wrl); poperror(); } . 496,497c if(mntflush(m, r) == 0) nexterror(); . 367d 355a if(q->flushed == 0) print("mail philw: %lux: not flushed\n", q); . 353a mntfree(r); . ## diffname port/devmnt.c 1991/0926 ## diff -e /n/bootesdump/1991/0925/sys/src/9/port/devmnt.c /n/bootesdump/1991/0926/sys/src/9/port/devmnt.c 450c r->request.count = limit(n, m->blocksize); . 154a m->blocksize = MAXFDATA; . 37a int blocksize; /* read/write block size */ . ## diffname port/devmnt.c 1991/1004 ## diff -e /n/bootesdump/1991/0926/sys/src/9/port/devmnt.c /n/bootesdump/1991/1004/sys/src/9/port/devmnt.c 378c mntdoclunk(m, r); poperror(); } void mntdoclunk(Mnt *m, Mntrpc *r) { Mntrpc *q; mntfree(r); if(decref(m) == 0) { for(q = m->queue; q; q = r) { r = q->list; q->flushed = 0; mntfree(q); } m->id = 0; close(m->c); lock(&mntalloc); m->list = mntalloc.mntfree; mntalloc.mntfree = m; unlock(&mntalloc); } . 356,372c mntdoclunk(m, r); nexterror(); . 351c Mntrpc *r; . 68a void mntdoclunk(Mnt *, Mntrpc *); . ## diffname port/devmnt.c 1991/1011 ## diff -e /n/bootesdump/1991/1004/sys/src/9/port/devmnt.c /n/bootesdump/1991/1011/sys/src/9/port/devmnt.c 664,666c if(m->mux) (*devtab[m->c->type].write)(m->c, r->flush, n, 0); else { qlock(&m->c->wrl); (*devtab[m->c->type].write)(m->c, r->flush, n, 0); qunlock(&m->c->wrl); } . 658c if(!m->mux) qunlock(&m->c->wrl); . 567,568c if(m->mux) n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); else { qlock(&m->c->rdl); n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); qunlock(&m->c->rdl); } . 564d 556c if(!m->mux) qunlock(&m->c->rdl); . 512,515c if(m->mux) { if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Eshortmsg); } else { qlock(&m->c->wrl); if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Eshortmsg); qunlock(&m->c->wrl); } . 507c if(!m->mux) qunlock(&m->c->wrl); . 156a m->c->flag |= CMSG; . ## diffname port/devmnt.c 1991/1105 ## diff -e /n/bootesdump/1991/1011/sys/src/9/port/devmnt.c /n/bootesdump/1991/1105/sys/src/9/port/devmnt.c 195c memmove(r->request.uname, u->p->user, NAMELEN); . ## diffname port/devmnt.c 1992/0111 ## diff -e /n/bootesdump/1991/1105/sys/src/9/port/devmnt.c /n/bootesdump/1992/0111/sys/src/9/port/devmnt.c 673c if(strcmp(u->error, Eintr) == 0) . 485c error(Eintr); . 6c #include "../port/error.h" . ## diffname port/devmnt.c 1992/0112 ## diff -e /n/bootesdump/1992/0111/sys/src/9/port/devmnt.c /n/bootesdump/1992/0112/sys/src/9/port/devmnt.c 483c error(r->reply.ename); . ## diffname port/devmnt.c 1992/0113 ## diff -e /n/bootesdump/1992/0112/sys/src/9/port/devmnt.c /n/bootesdump/1992/0113/sys/src/9/port/devmnt.c 521c error(Emountrpc); . 516c error(Emountrpc); . 490c error(Emountrpc); . ## diffname port/devmnt.c 1992/0114 ## diff -e /n/bootesdump/1992/0113/sys/src/9/port/devmnt.c /n/bootesdump/1992/0114/sys/src/9/port/devmnt.c 146c exhausted("mount devices"); . ## diffname port/devmnt.c 1992/0301 ## diff -e /n/bootesdump/1992/0114/sys/src/9/port/devmnt.c /n/bootesdump/1992/0301/sys/src/9/port/devmnt.c 108c rd->rpc = ialloc(i, 0); . 101a /* Align mount buffers to 256 byte boundaries so we can use burst mode vme transfers */ p = (ulong)ialloc(0, 0); if(p&(ALIGN-1)) ialloc(ALIGN-(p&(ALIGN-1)), 0); i = MAXRPC+(ALIGN-1); i &= ~(ALIGN-1); . 83a ulong p; int i; . 75a ALIGN = 256, /* Vme block mode alignment */ . ## diffname port/devmnt.c 1992/0305 ## diff -e /n/bootesdump/1992/0301/sys/src/9/port/devmnt.c /n/bootesdump/1992/0305/sys/src/9/port/devmnt.c 809c r->done, r->flushed); . 806c print("%.8lux %.8lux T%d R%d tags req %d fls %d rep %d d %d f %d\n", . 728,735d 717c new->flushed = 0; . 699,702d 674,676c lock(m); r->flushtag = m->flushtag++; if(m->flushtag == Tagend) m->flushtag = m->flushbase; r->flushed = 1; unlock(m); . 656,665d 647,650c if(q != r) { /* Completed someone else */ dp = q->rpc; q->rpc = r->rpc; r->rpc = dp; memmove(&q->reply, &r->reply, sizeof(Fcall)); q->done = 1; wakeup(&q->r); }else q->done = 1; . 643,645d 634,641c if(q->request.tag == r->reply.tag || q->flushed && q->flushtag == r->reply.tag) { . 628d 512a r->flushed = 0; . 502a mntdump(); . 493a r->reply.type = 4; /* safety check */ . 123a for(md = mntalloc.mntfree; md < me; md++){ md->list = md+1; md->flushbase = tag; md->flushtag = tag; } me[-1].list = 0; . 118,120d 114a tag = Tagspace; . 96,102d 92,94d 85c ushort tag; . 74,75c Tagend = 0xfffe, . 38a ushort flushtag; /* Tag to send flush on */ ushort flushbase; /* Base tag of flush window for this buffer */ . 24,25c ushort flushtag; /* Tag flush sent on */ . 22d ## diffname port/devmnt.c 1992/0312 ## diff -e /n/bootesdump/1992/0305/sys/src/9/port/devmnt.c /n/bootesdump/1992/0312/sys/src/9/port/devmnt.c 251a USED(alloc); . 203d 193a if(*serv && !waserror()){ r->request.type = Tauth; r->request.fid = c->fid; memmove(r->request.uname, u->p->user, NAMELEN); chal[0] = 1; for(i = 1; i < sizeof chal; i++) chal[i++] = nrand(256); memmove(r->request.chal, chal, 8); strncpy(r->request.chal+8, serv, NAMELEN); encrypt(u->p->pgrp->crypt->key, r->request.chal, 8+NAMELEN); mountrpc(m, r); decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*8+2*DESKEYLEN); chal[0] = 4; if(memcmp(chal, r->reply.chal, 8) != 0) error(Eperm); memmove(r->request.auth, r->reply.chal+8+DESKEYLEN, 8+DESKEYLEN); poperror(); }else memset(r->request.auth, 0, sizeof r->request.auth); . 184a char chal[8]; int i; . 181c mattach(Mnt *m, char *spec, char *serv) . 177c return mattach(m, bogus.spec, bogus.serv); . 144c return mattach(m, bogus.spec, bogus.serv); . 133c char *serv; . ## diffname port/devmnt.c 1992/0313 ## diff -e /n/bootesdump/1992/0312/sys/src/9/port/devmnt.c /n/bootesdump/1992/0313/sys/src/9/port/devmnt.c 519d ## diffname port/devmnt.c 1992/0314 ## diff -e /n/bootesdump/1992/0313/sys/src/9/port/devmnt.c /n/bootesdump/1992/0314/sys/src/9/port/devmnt.c 216,220d 206,212c if(waserror()) memset(r->request.auth, 0, sizeof r->request.auth); else{ mountrpc(m, r); poperror(); decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*8+2*DESKEYLEN); chal[0] = 4; if(memcmp(chal, r->reply.chal, 8) != 0) error(Eperm); memmove(r->request.auth, r->reply.chal+8+DESKEYLEN, 8+DESKEYLEN); } r->done = 0; r->flushed = 0; . 196c if(waserror()){ mntfree(r); close(c); nexterror(); } if(*serv){ . 189d ## diffname port/devmnt.c 1992/0315 ## diff -e /n/bootesdump/1992/0314/sys/src/9/port/devmnt.c /n/bootesdump/1992/0315/sys/src/9/port/devmnt.c 108c rd->rpc = iallocspan(MAXRPC, ALIGN, 0); . 96,103c /* * Align mount buffers to 256 byte boundaries * so we can use burst mode vme transfers */ . ## diffname port/devmnt.c 1992/0317 ## diff -e /n/bootesdump/1992/0315/sys/src/9/port/devmnt.c /n/bootesdump/1992/0317/sys/src/9/port/devmnt.c 168a case 'H': /* Cyclone */ m->mux = 1; break; . 163,166d ## diffname port/devmnt.c 1992/0318 ## diff -e /n/bootesdump/1992/0317/sys/src/9/port/devmnt.c /n/bootesdump/1992/0318/sys/src/9/port/devmnt.c 793,794c print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n", m->id, m->mux, m->queue, m->rip, . 235a void mntauth(Mnt *m, Mntrpc *f, char *serv, ushort fid) { Mntrpc *r; uchar chal[CHLEN]; int i; r = mntralloc(); if(waserror()) { mntfree(r); return; } r->request.type = Tauth; r->request.fid = fid; memmove(r->request.uname, u->p->user, NAMELEN); chal[0] = FScchal; for(i = 1; i < CHLEN; i++) chal[i++] = nrand(256); memmove(r->request.chal, chal, CHLEN); strncpy(r->request.chal+CHLEN, serv, NAMELEN); encrypt(u->p->pgrp->crypt->key, r->request.chal, CHLEN+NAMELEN); mountrpc(m, r); decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*CHLEN+2*DESKEYLEN); chal[0] = FSctick; poperror(); if(memcmp(chal, r->reply.chal, CHLEN) != 0) { mntfree(r); error(Eperm); } memmove(f->request.auth, r->reply.chal+CHLEN+DESKEYLEN, CHLEN+DESKEYLEN); mntfree(r); } . 221a . 196,220c memset(r->request.auth, 0, sizeof r->request.auth); if(*serv) mntauth(m, r, serv, c->fid); . 180,181d 164a break; . 161a /* If we have a stream based protocol (TCP/IP) we push fcall to block * up P9 protocol messages into single deliminted blocks */ s = m->c->stream; qi = qinfofind("fcall"); if(s) if(s->procq->next) if(s->procq->next->info->nodelim) { if(qi == 0) error(Ebadctl); pushq(s, qi); } . 125a Stream *s; Qinfo *qi; . 69a void mntauth(Mnt *, Mntrpc *, char *, ushort); . ## diffname port/devmnt.c 1992/0320 ## diff -e /n/bootesdump/1992/0318/sys/src/9/port/devmnt.c /n/bootesdump/1992/0320/sys/src/9/port/devmnt.c 446a } void mntpntfree(Mnt *m) { lock(&mntalloc); m->list = mntalloc.mntfree; mntalloc.mntfree = m; unlock(&mntalloc); . 442,445c mntpntfree(m); . 215d 207c /* Close must not be called since it will call mnt recursively */ chanfree(c); . 189c if(waserror()) { close(m->c); mntpntfree(m); nexterror(); } /* If we have a stream based protocol (TCP/IP) we push fcall to block * up P9 protocol messages into single deliminted blocks */ s = m->c->stream; qi = qinfofind("fcall"); if(s) if(s->procq->next) if(s->procq->next->info->nodelim) { if(qi == 0) error(Ebadctl); pushq(s, qi); } c = mattach(m, bogus.spec, bogus.serv); poperror(); return c; . 165,176d 140c if(m->id && m->ref > 0 && m->c == bogus.chan) { . 128a Chan *c; . 70a void mntpntfree(Mnt*); . ## diffname port/devmnt.c 1992/0321 ## diff -e /n/bootesdump/1992/0320/sys/src/9/port/devmnt.c /n/bootesdump/1992/0321/sys/src/9/port/devmnt.c 2c #include "../port/lib.h" . ## diffname port/devmnt.c 1992/0322 ## diff -e /n/bootesdump/1992/0321/sys/src/9/port/devmnt.c /n/bootesdump/1992/0322/sys/src/9/port/devmnt.c 272c memmove(f->request.auth, r->reply.chal+AUTHLEN+DESKEYLEN, AUTHLEN+DESKEYLEN); . 268c if(memcmp(chal, r->reply.chal, AUTHLEN) != 0) { . 265c decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*AUTHLEN+2*DESKEYLEN); . 260,262c memmove(r->request.chal, chal, AUTHLEN); strncpy(r->request.chal+AUTHLEN, serv, NAMELEN); encrypt(u->p->pgrp->crypt->key, r->request.chal, AUTHLEN+NAMELEN); . 257c for(i = 1; i < AUTHLEN; i++) . 244c uchar chal[AUTHLEN]; . ## diffname port/devmnt.c 1992/0325 ## diff -e /n/bootesdump/1992/0322/sys/src/9/port/devmnt.c /n/bootesdump/1992/0325/sys/src/9/port/devmnt.c 181c if(decref(m) == 0) mntpntfree(m); . ## diffname port/devmnt.c 1992/0402 ## diff -e /n/bootesdump/1992/0325/sys/src/9/port/devmnt.c /n/bootesdump/1992/0402/sys/src/9/port/devmnt.c 186,197d 128,129d ## diffname port/devmnt.c 1992/0503 ## diff -e /n/bootesdump/1992/0402/sys/src/9/port/devmnt.c /n/bootesdump/1992/0503/sys/src/9/port/devmnt.c 649a if(n > 2048) for(i = 0; i < 256;) { print("%.2ux ", r->rpc[i] & 0xff); i++; if((i%16) == 0) { print("\n"); prflush(); } } . 626c int i; . 578a . 570a memset(r->rpc, 0x55, 2048); . ## diffname port/devmnt.c 1992/0505 ## diff -e /n/bootesdump/1992/0503/sys/src/9/port/devmnt.c /n/bootesdump/1992/0505/sys/src/9/port/devmnt.c 652,657d 628c . 571d ## diffname port/devmnt.c 1992/0520 ## diff -e /n/bootesdump/1992/0505/sys/src/9/port/devmnt.c /n/bootesdump/1992/0520/sys/src/9/port/devmnt.c 760a return 0; /* not reached */ . ## diffname port/devmnt.c 1992/0603 ## diff -e /n/bootesdump/1992/0520/sys/src/9/port/devmnt.c /n/bootesdump/1992/0603/sys/src/9/port/devmnt.c 245c chal[i] = nrand(256); . ## diffname port/devmnt.c 1992/0613 ## diff -e /n/bootesdump/1992/0603/sys/src/9/port/devmnt.c /n/bootesdump/1992/0613/sys/src/9/port/devmnt.c 543,544c r->reply.tag = 0; /* safety checks */ r->reply.type = 4; . 51,52c #define MAXRPC (MAXFDATA+MAXMSG) . ## diffname port/devmnt.c 1992/0619 ## diff -e /n/bootesdump/1992/0613/sys/src/9/port/devmnt.c /n/bootesdump/1992/0619/sys/src/9/port/devmnt.c 8d ## diffname port/devmnt.c 1992/0620 ## diff -e /n/bootesdump/1992/0619/sys/src/9/port/devmnt.c /n/bootesdump/1992/0620/sys/src/9/port/devmnt.c 817,841d 798c if(m->id == 0 || m->id >= c->dev) /* Sanity check */ . 796c m = c->mntptr; . 759c unlock(&mntalloc); new->done = 0; new->flushed = 0; return new; . 756,757c new->rpc = (char*)new+sizeof(Mntrpc); new->request.tag = mntalloc.rpctag++; . 752,754c exhausted("mount rpc buffer"); . 747,750c lock(&mntalloc); new = mntalloc.rpcfree; if(new != 0) mntalloc.rpcfree = new->list; else { new = xalloc(sizeof(Mntrpc)+MAXRPC); if(new == 0) { . 550,551c print("mnt: mismatched reply 0x%lux T%d R%d tags req %d fls %d rep %d\n", r, r->request.type, r->reply.type, r->request.tag, r->flushtag, r->reply.tag); . 545a . 542a . 541c r->reply.tag = 0; /* poison the old values */ . 445a l = &mntalloc.list; for(f = *l; f; f = f->list) { if(f == m) { *l = m->list; break; } l = &f->list; } . 444a Mnt *f, **l; . 198c c->mntptr = m; . 168c case 'C': /* Cyclone */ . 163d 159c m->c = c; . 155a . 152c if(m != 0) mntalloc.mntfree = m->list; else { m = malloc(sizeof(Mnt)); if(m == 0) { unlock(&mntalloc); exhausted("mount devices"); } m->flushbase = Tagfls; m->flushtag = Tagfls; } m->list = mntalloc.list; mntalloc.list = m; . 146,150d 138c if(m->id && m->ref > 0 && m->c == c) { unlock(&mntalloc); . 134,136c c = bogus.chan; lock(&mntalloc); for(m = mntalloc.list; m; m = m->list) { if(m->c == c && m->id) { . 125c Mnt *m; . 114a mntalloc.rpctag = Tagspace; . 82,113d 73a Tagfls = 0x8000, . 47a int rpctag; . 46d 43,44c Mnt *list; /* Mount devices in used */ Mnt *mntfree; /* Free list */ . 10,11d ## diffname port/devmnt.c 1992/0824 ## diff -e /n/bootesdump/1992/0620/sys/src/9/port/devmnt.c /n/bootesdump/1992/0824/sys/src/9/port/devmnt.c 253c if(waserror()) { . ## diffname port/devmnt.c 1992/0825 ## diff -e /n/bootesdump/1992/0824/sys/src/9/port/devmnt.c /n/bootesdump/1992/0825/sys/src/9/port/devmnt.c 724,730c (*devtab[m->c->type].write)(m->c, r->flush, n, 0); . 717,718d 702a Fcall flush; . 701d 673a Mntrpc **l, *q; . 672d 632,638c n = (*devtab[m->c->type].read)(m->c, r->rpc, MAXRPC, 0); . 621,622d 570,580c if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Emountrpc); . 564,565d 497a ulong cnt, nr; . 496d 208d 205a int i; . 67a void mntqrm(Mnt*, Mntrpc*); Mntrpc* mntralloc(void); long mntrdwr(int , Chan*, void*,long , ulong); void mntrpcread(Mnt*, Mntrpc*); void mountio(Mnt*, Mntrpc*); void mountmux(Mnt*, Mntrpc*); void mountrpc(Mnt*, Mntrpc*); int rpcattn(Mntrpc*); . 66c int mntflush(Mnt*, Mntrpc*); void mntfree(Mntrpc*); void mntgate(Mnt*); . 63,64d 51,61c Chan* mattach(Mnt*, char*, char*); void mntauth(Mnt *, Mntrpc *, char *, ushort); Mnt* mntchk(Chan*); . ## diffname port/devmnt.c 1992/0915 ## diff -e /n/bootesdump/1992/0825/sys/src/9/port/devmnt.c /n/bootesdump/1992/0915/sys/src/9/port/devmnt.c 140c m->blocksize = MAXFDATA;/**/ . ## diffname port/devmnt.c 1992/1217 ## diff -e /n/bootesdump/1992/0915/sys/src/9/port/devmnt.c /n/bootesdump/1992/1217/sys/src/9/port/devmnt.c 776,777c *(ushort*)&dirbuf[DIRLEN-4] = devchar[c->type]; . ## diffname port/devmnt.c 1992/1223 ## diff -e /n/bootesdump/1992/1217/sys/src/9/port/devmnt.c /n/bootesdump/1992/1223/sys/src/9/port/devmnt.c 776c dirbuf[DIRLEN-4] = devchar[c->type]>>0; dirbuf[DIRLEN-3] = devchar[c->type]>>8; . ## diffname port/devmnt.c 1993/0304 ## diff -e /n/bootesdump/1992/1223/sys/src/9/port/devmnt.c /n/bootesdump/1993/0304/sys/src/9/port/devmnt.c 265,274c devclone(c, nc); . ## diffname port/devmnt.c 1993/0321 ## diff -e /n/bootesdump/1993/0304/sys/src/9/port/devmnt.c /n/bootesdump/1993/0321/sys/src/9/port/devmnt.c 398,408c if(decref(m) != 0) return; for(q = m->queue; q; q = r) { r = q->list; q->flushed = 0; mntfree(q); } m->id = 0; close(m->c); mntpntfree(m); } void mntdoclunk(Mnt *m, Mntrpc *r) { mntfree(r); mclose(m); . 396c Mntrpc *q, *r; . 394c mclose(Mnt *m) . 160a mc = m->c; if(mc->type == devno('M', 0)) { c->mntptr = mc->mntptr; c->mchan = c->mntptr->c; c->mqid = c->qid; incref(c->mntptr); mclose(m); } . 154,156c mclose(m); . 116a . 94c Chan *c, *mc; . 67a void mclose(Mnt*); . 32c char mux; /* Set if the device does the multiplexing */ . ## diffname port/devmnt.c 1993/0323 ## diff -e /n/bootesdump/1993/0321/sys/src/9/port/devmnt.c /n/bootesdump/1993/0323/sys/src/9/port/devmnt.c 165c c->mchan = mc->mntptr->c; . 163c if(mc->type == devno('M', 0) && (c->qid.path&CHDIR) == 0) { c->qid.path |= CHDIR; . ## diffname port/devmnt.c 1993/0330 ## diff -e /n/bootesdump/1993/0323/sys/src/9/port/devmnt.c /n/bootesdump/1993/0330/sys/src/9/port/devmnt.c 212,248d 204a authreply(m->c->session, id, &r->reply); . 203a id = authrequest(m->c->session, &r->request); . 196,199d 180a ulong id; . 177c mattach(Mnt *m, char *spec) . 161a /* * If exportfs mounts on behalf of a local devmnt, the mount * point is folded onto the original channel to preserve a single * fid/tag space. CHDIR is cleared by exportfs to indicate it * is supplying the mount. */ . 160c c = mattach(m, bogus.spec); . 113c return mattach(m, bogus.spec); . 99d 51,52c Chan* mattach(Mnt*, char*); . ## diffname port/devmnt.c 1993/0403 ## diff -e /n/bootesdump/1993/0330/sys/src/9/port/devmnt.c /n/bootesdump/1993/0403/sys/src/9/port/devmnt.c 203c memmove(r->request.uname, up->user, NAMELEN); . 196c /* Close must not be called since * it will call mnt recursively */ . ## diffname port/devmnt.c 1993/0404 ## diff -e /n/bootesdump/1993/0403/sys/src/9/port/devmnt.c /n/bootesdump/1993/0404/sys/src/9/port/devmnt.c 205c memmove(r->request.uname, u->p->user, NAMELEN); . ## diffname port/devmnt.c 1993/0417 ## diff -e /n/bootesdump/1993/0404/sys/src/9/port/devmnt.c /n/bootesdump/1993/0417/sys/src/9/port/devmnt.c 498c n -= nr; if(nr != r->request.count || n == 0) . 478c cnt = 0; for(;;) { . ## diffname port/devmnt.c 1993/0501 ## diff -e /n/bootesdump/1993/0417/sys/src/9/port/devmnt.c /n/fornaxdump/1993/0501/sys/src/brazil/port/devmnt.c 764a } int recdone(Mnt *m) { return m->recprog == 0; } void mntrecdel(Mnt *m, Mntrpc *r) { Mntrpc *f, **l; lock(m); l = &m->recwait; for(f = *l; f; f = f->list) { if(f == r) { *l = r->list; break; } } unlock(m); } void mntrecover(Mnt *m, Mntrpc *r) { char *ps; lock(m); if(m->recprog == 0) { m->recprog = 1; unlock(m); chanrec(m); /* * Send a message to boot via #/recover */ rootrecover(m->c->path, m->tree.root->elem); lock(m); } r->list = m->recwait; m->recwait = r; unlock(m); pprint("lost server connection, wait...\n"); ps = up->psstate; up->psstate = "Recover"; if(waserror()) { up->psstate = ps; mntrecdel(m, r); nexterror(); } sleep(&r->r, recdone, m); poperror(); r->done = 0; mntrecdel(m, r); recoverchan(m, r->c); up->psstate = ps; } void mntrepl(char *buf) { int fd; Mnt *m; char *p; Chan *c1; Mntrpc *r; /* reply from boot is 'fd #M23' */ fd = strtoul(buf, &p, 0); p++; lock(&mntalloc); for(m = mntalloc.list; m; m = m->list) { if(strcmp(p, m->tree.root->elem) == 0) break; } unlock(&mntalloc); if(m == 0) error(Eunmount); c1 = fdtochan(fd, ORDWR, 0, 1); /* error check and inc ref */ /* If the channel was posted fix it up */ srvrecover(m->c, c1); lock(m); close(m->c); m->c = c1; m->recprog = 0; /* Wakeup partially complete rpc */ for(r = m->recwait; r; r = r->list) wakeup(&r->r); unlock(m); . 748a /* * Try and get the channel back */ if((c->flag&CRECOV) && m->recprog == 0) recoverchan(m, c); . 746,747c /* * Was it closed and reused */ if(m->id == 0 || m->id >= c->dev) . 739a void recoverchan(Mnt *m, Chan *c) { int i, n, flg; Path *safe, *p, **pav; if(m->c == 0) error(Eshutdown); flg = c->flag; /* Don't recursively recover */ c->flag &= ~(COPEN|CRECOV); n = 0; for(p = c->path; p; p = p->parent) n++; pav = smalloc(sizeof(Path*)*n); i = n; for(p = c->path; p; p = p->parent) pav[--i] = p; safe = c->path; if(waserror()) { c->flag = flg; free(pav); nexterror(); } /* Attach the fid onto the file server (sets c->path to #Mxxx) */ mattach(m, c, c->xmnt->spec); poperror(); /* * c is now at the root so we free where * the chan was before the server connection was lost */ decref(safe); for(i = 1; i < n; i++) { if(mntwalk(c, pav[i]->elem) == 0) { free(pav); /* Shut down the channel */ c->dev = m->id-1; error(Erecover); } } free(pav); if(flg&COPEN) mntopen(c, c->mode); } . 705a new->c = c; . 688c mntralloc(Chan *c) . 677c if(strcmp(up->error, Eintr) == 0) . 646c q->reply = r->reply; . 625a } . 615c for(q = m->queue; q; q = q->list) { . 573c m->rip = up; . 518,523c default: if(t == r->request.type+1) break; print("mnt: mismatch rep 0x%lux T%d R%d rq %d fls %d rp %d\n", r, t, r->reply.type, r->request.tag, r->flushtag, r->reply.tag); . 516c t = r->reply.type; switch(t) { case Rerror: error(r->reply.ename); case Rflush: . 513,514c poperror(); . 511a while(waserror()) { if(m->recov == 0) nexterror(); mntrecover(m, r); } . 509c int t; r->reply.tag = 0; . 499,500c if(nr != r->request.count) . 478,480c for(cnt = 0; n; n -= nr) { r = mntralloc(c); . 436c r = mntralloc(c); . 391,397d 379a c->path = 0; ptclose(&m->tree); . 373c mclose(Mnt *m, Chan *c) . 368c mntfree(r); mclose(m, c); . 361c mntfree(r); mclose(m, c); . 359c r = mntralloc(c); . 333c r = mntralloc(c); . 307c r = mntralloc(c); . 285c r = mntralloc(c); . 271a op = c->path; c->path = ptenter(&m->tree, op, name); /* ASSERT */ if(op->ref == 0) { char buf[128]; ptpath(op, buf, sizeof(buf)); print("PATH: '%s' walking %s\n", op, name); } decref(op); . 261c r = mntralloc(c); . 257a Path *op; . 227c r = mntralloc(c); . 216d 213a c->path = m->tree.root; incref(c->path); . 205c memmove(r->request.uname, up->user, NAMELEN); . 196,199d 191a return c; } void mattach(Mnt *m, Chan *c, char *spec) { ulong id; Mntrpc *r; r = mntralloc(0); . 187,188c c = devattach('M', 0); . 184,185d 180,181c Chan* mntchan(void) . 176d 173d 171a c->path = c->mntptr->tree.root; incref(c->path); . 170c c->mchan = c->mntptr->c; . 167a mclose(m, c); . 160,165d 158c mattach(m, c, bogus.spec); poperror(); . 154c mclose(m, c); /* Close must not be called since it will * call mnt recursively */ chanfree(c); . 152a c = mntchan(); . 150a sprint(buf, "#M%d", m->id); m->tree.root = ptenter(&m->tree, 0, buf); . 140c m->blocksize = MAXFDATA; /**/ m->recov = bogus.recov; . 116d 111c c = mntchan(); if(waserror()) { chanfree(c); nexterror(); } mattach(m, c, bogus.spec); poperror(); return c; . 97a char recov; . 94a char buf[NAMELEN]; . 67c void mclose(Mnt*, Chan*); void mntrecover(Mnt*, Mntrpc*); Chan* mntchan(void); . 60c Mntrpc* mntralloc(Chan*); . 54d 51c void mattach(Mnt*, Chan*, char*); void mntauth(Mnt *, Mntrpc *, char *, ushort); . 41c Mnt *list; /* Mount devices in use */ . 24,37d 11a Chan *c; /* Channel for whom we are working */ . 9d ## diffname port/devmnt.c 1993/0808 ## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/0808/sys/src/brazil/port/devmnt.c 288a . 283c /* ASSERT do not remove */ . 167a while(mc) { if(mc->type != devno('M', 0)) break; nest++; if(mc->mntptr == 0) break; mc = mc->mntptr->c; } m->blocksize -= nest * 32; /* * Detect a recursive mount for a mount point served by exportfs. * If CHDIR is clear in the returned qid the foreign server is * requesting the mount point be folded into the connection * to the exportfs. In this case the remote mount driver does * the multiplexing. */ mc = m->c; . 166a /* Work out how deep we are nested and reduce the blocksize * accordingly */ nest = 0; . 81a int nest; . ## diffname port/devmnt.c 1993/0907 ## diff -e /n/fornaxdump/1993/0808/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/0907/sys/src/brazil/port/devmnt.c 539c n -= nr; if(nr != r->request.count || n == 0) . 531a if(nr > r->request.count) nr = r->request.count; . 519c cnt = 0; for(;;) { . ## diffname port/devmnt.c 1993/1006 ## diff -e /n/fornaxdump/1993/0907/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1006/sys/src/brazil/port/devmnt.c 654a } . 653c if(n == 0) { if(++zrd > 3) error(Ehungup); . 639a zrd = 0; . 638c int n, zrd; . ## diffname port/devmnt.c 1993/1011 ## diff -e /n/fornaxdump/1993/1006/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1011/sys/src/brazil/port/devmnt.c 865c * Try and get the channel back after a crash . 59,63c Tagspace = 1, Tagfls = 0x8000, Tagend = 0xfffe, . ## diffname port/devmnt.c 1993/1014 ## diff -e /n/fornaxdump/1993/1011/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1014/sys/src/brazil/port/devmnt.c 556c if((m->flags & MRECOV) == 0) . 515d 510d 508c mntrdwr(int type, Mnt *m, Chan *c, void *buf, long n, ulong offset) . 504c m = mntchk(c); return mntrdwr(Twrite, m, c, buf, n, offset); . 497a if(nc != 0) cupdate(c, buf, n, offset); . 493c m = mntchk(c); nc = 0; if((m->flags&MCACHE) && !isdir(c)) { nc = cread(c, buf, n, offset); if(nc == n) return n; buf = (uchar*)buf+nc; offset += nc; n -= nc; } n = mntrdwr(Tread, m, c, buf, n, offset); . 490a int nc; . 305,311d 136c m->flags = bogus.flags; . 86c int flag; . 47c long mntrdwr(int , Mnt*, Chan*, void*,long , ulong); . ## diffname port/devmnt.c 1993/1015 ## diff -e /n/fornaxdump/1993/1014/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1015/sys/src/brazil/port/devmnt.c 542a else if(cache) cwrite(c, (uchar*)r->reply.data, nr, offset); . 540a . 525a cache = m->flags & MCACHE; . 521a int cache; . 513,514c return mntrdwr(Twrite, mntchk(c), c, buf, n, offset); . 505a n += nc; } . 504c if(cached) { . 494,496c SET(nc); if(cached) { nc = cread(c, buf, n, offset); if(nc > 0) { buf = (uchar*)buf+nc; offset += nc; n -= nc; } . 488,492c cached = m->flags&MCACHE; . 485a int nc, cached; . 484c Mnt *m; . 383a if(m->flags & MCACHE) copen(c); . 356a if(m->flags&MCACHE) copen(c); . 111a . 94c if(m->c == c && m->id && m->flags == bogus.flags) { . 86c int flags; . 68a cinit(); . ## diffname port/devmnt.c 1993/1016 ## diff -e /n/fornaxdump/1993/1015/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1016/sys/src/brazil/port/devmnt.c 583c if((m->flags&MRECOV) == 0) . 560c cwrite(c, (uchar*)uba, nr, offset); . 540c cache = c->flag & CCACHE; . 537a m = mntchk(c); . 533c Mnt *m; Mntrpc *r; . 531c mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) . 527c return mntrdwr(Twrite, c, buf, n, offset); . 515,516c } else if(cached) { . 511,512c n = mntrdwr(Tread, c, buf, n, offset); if(c->qid.path & CHDIR) { . 498,499c cached = c->flag & CCACHE; . 494d 392c if(c->flag & CCACHE) . 361c if(c->flag & CCACHE) . 202a if(bogus.flags & MCACHE) c->flag |= CCACHE; . 139c m->flags = bogus.flags & ~MCACHE; . 108a if(bogus.flags&MCACHE) c->flag |= CCACHE; . 96c if(m->c == c && m->id) { . 47c long mntrdwr(int , Chan*, void*,long , ulong); . ## diffname port/devmnt.c 1993/1102 ## diff -e /n/fornaxdump/1993/1016/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1102/sys/src/brazil/port/devmnt.c 573c if(nr != r->request.count || n == 0 || up->nnote) . 510d 507a n -= nc; if(n == 0) return nc; . ## diffname port/devmnt.c 1993/1103 ## diff -e /n/fornaxdump/1993/1102/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1103/sys/src/brazil/port/devmnt.c 690d 686,688c if(n == 0) . 672d 670c int n; . ## diffname port/devmnt.c 1993/1105 ## diff -e /n/fornaxdump/1993/1103/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1105/sys/src/brazil/port/devmnt.c 607c r, r->request.type, r->reply.type, r->request.tag, . ## diffname port/devmnt.c 1993/1122 ## diff -e /n/fornaxdump/1993/1105/sys/src/brazil/port/devmnt.c /n/fornaxdump/1993/1122/sys/src/brazil/port/devmnt.c 1014a } static uchar msglen[256] = { [Tnop] 3, [Rnop] 3, [Tsession] 3+CHALLEN, [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, [Terror] 0, [Rerror] 67, [Tflush] 5, [Rflush] 3, [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, [Rattach] 13+AUTHENTLEN, [Tclone] 7, [Rclone] 5, [Twalk] 33, [Rwalk] 13, [Topen] 6, [Ropen] 13, [Tcreate] 38, [Rcreate] 13, [Tread] 15, [Rread] 8, [Twrite] 16, [Rwrite] 7, [Tclunk] 5, [Rclunk] 5, [Tremove] 5, [Rremove] 5, [Tstat] 5, [Rstat] 121, [Twstat] 121, [Rwstat] 5, [Tclwalk] 35, [Rclwalk] 13, }; enum { Twritehdr = 16, /* Min bytes for Twrite */ Rreadhdr = 8, /* Min bytes for Rread */ Twritecnt = 13, /* Offset in byte stream of write count */ Rreadcnt = 5, /* Offset for Readcnt */ }; int mntrpclen(char *d, int n) { char t; int len, off; if(n < 1) return 0; t = d[0]; switch(t) { /* This is the type */ default: len = msglen[t]; if(len == 0) /* Illegal type so consume */ return n; if(n < len) return 0; return len; case Twrite: /* Fmt: TGGFFOOOOOOOOCC */ len = Twritehdr; /* T = type, G = tag, F = fid */ off = Twritecnt; /* O = offset, C = count */ break; case Rread: /* Fmt: TGGFFCC */ len = Rreadhdr; off = Rreadcnt; break; } if(n < off+2) return 0; len += d[off]+(d[off+1]<<8); if(n < len) return 0; return len; . 683c n = devtab[m->c->type].read(m->c, r->rpc, MAXRPC, 0); . 55a int mntrpclen(char*, int); . ## diffname port/devmnt.c 1994/0107 ## diff -e /n/fornaxdump/1993/1122/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/0107/sys/src/brazil/port/devmnt.c 1016,1096d 56d ## diffname port/devmnt.c 1994/0402 ## diff -e /n/fornaxdump/1994/0107/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/0402/sys/src/brazil/port/devmnt.c 632,633c if(devchar[m->c->type] == L'M'){ if(mntwrite9p(m->c, r->rpc, n, 0) != n) error(Emountrpc); }else{ if((*devtab[m->c->type].write)(m->c, r->rpc, n, 0) != n) error(Emountrpc); } . 558c if(p9msg) r->request.count = limit(n, m->blocksize + MAXMSG - 20); else r->request.count = limit(n, m->blocksize); . 536c mntrdwr(int type, Chan *c, void *buf, long n, ulong offset, int p9msg) . 532c return mntrdwr(Twrite, c, buf, n, offset, 0); . 529a mntwrite9p(Chan *c, void *buf, long n, ulong offset) { return mntrdwr(Twrite, c, buf, n, offset, 1); } long . 516c n = mntrdwr(Tread, c, buf, n, offset, 0); . 184a #endif STUPIDHACK . 170a #ifdef STUPIDHACK . 47c long mntrdwr(int , Chan*, void*,long , ulong, int); . ## diffname port/devmnt.c 1994/0405 ## diff -e /n/fornaxdump/1994/0402/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/0405/sys/src/brazil/port/devmnt.c 699c if(devchar[m->c->type] == L'M') n = mntrdwr(Tread, m->c, r->rpc, MAXRPC, 0, 1); else n = devtab[m->c->type].read(m->c, r->rpc, MAXRPC, 0); . 644c if(mntrdwr(Twrite, m->c, r->rpc, n, 0, 1) != n) . 566,568c if(p9msg) { if(n > MAXRPC-32){ if(type == Twrite) error("write9p too long"); n = MAXRPC-32; } r->request.count = n; } else . 498a mntread9p(Chan *c, void *buf, long n, ulong offset) { return mntrdwr(Tread, c, buf, n, offset, 1); } long . 171,187d 82d ## diffname port/devmnt.c 1994/0513 ## diff -e /n/fornaxdump/1994/0405/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/0513/sys/src/brazil/port/devmnt.c 139c m->blocksize = defmaxmsg; . 56a int defmaxmsg = MAXFDATA; . ## diffname port/devmnt.c 1994/0828 ## diff -e /n/fornaxdump/1994/0513/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/0828/sys/src/brazil/port/devmnt.c 782c l = (*devtab[m->c->type].write)(m->c, r->flush, n, 0); if(l != n) error(Ehungup); . 761c int n, l; . ## diffname port/devmnt.c 1994/0831 ## diff -e /n/fornaxdump/1994/0828/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/0831/sys/src/brazil/port/devmnt.c 141c if(strcmp(bogus.spec, "16k") == 0) { m->blocksize = 16*1024; bogus.spec = ""; } else m->blocksize = defmaxmsg; . 34c #define MAXRPC (16*1024+MAXMSG) . ## diffname port/devmnt.c 1994/1124 ## diff -e /n/fornaxdump/1994/0831/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/1124/sys/src/brazil/port/devmnt.c 30c ulong id; . ## diffname port/devmnt.c 1994/1212 ## diff -e /n/fornaxdump/1994/1124/sys/src/brazil/port/devmnt.c /n/fornaxdump/1994/1212/sys/src/brazil/port/devmnt.c 994c if(r->c != 0) recoverchan(m, r->c); . 224c if(waserror()) { . ## diffname port/devmnt.c 1995/0107 ## diff -e /n/fornaxdump/1994/1212/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0107/sys/src/brazil/port/devmnt.c 27,29c Mnt* list; /* Mount devices in use */ Mnt* mntfree; /* Free list */ Mntrpc* rpcfree; . 17c char* rpc; /* I/O Data buffer */ . 15c Mnt* m; /* Mount device during rpc */ . 11,12c Chan* c; /* Channel for whom we are working */ Mntrpc* list; /* Free/pending list */ . ## diffname port/devmnt.c 1995/0108 ## diff -e /n/fornaxdump/1995/0107/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0108/sys/src/brazil/port/devmnt.c 535a } long mntbwrite(Chan *c, Block *bp, ulong offset) { return devbwrite(c, bp, offset); . 525a Block* mntbread(Chan *c, long n, ulong offset) { return devbread(c, n, offset); } . ## diffname port/devmnt.c 1995/0129 ## diff -e /n/fornaxdump/1995/0108/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0129/sys/src/brazil/port/devmnt.c 712c n = mnt9prdwr(Tread, m->c, r->rpc, MAXRPC, 0); . 656c if(mnt9prdwr(Twrite, m->c, r->rpc, n, 0) != n) . 573,581c r->request.count = limit(n, m->blocksize); . 553a ulong nr; Mntrpc *r; if(n > MAXRPC-32) { if(type == Twrite) error("write9p too long"); n = MAXRPC-32; } m = mntchk(c); r = mntralloc(c); if(waserror()) { mntfree(r); nexterror(); } r->request.type = type; r->request.fid = c->fid; r->request.offset = offset; r->request.data = buf; r->request.count = n; mountrpc(m, r); nr = r->reply.count; if(nr > r->request.count) nr = r->request.count; if(type == Tread) memmove(buf, r->reply.data, nr); poperror(); mntfree(r); return nr; } long mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) { Mnt *m; . 551c mnt9prdwr(int type, Chan *c, void *buf, long n, ulong offset) . 541c return mntrdwr(Twrite, c, buf, n, offset); . 535c return mnt9prdwr(Twrite, c, buf, n, offset); . 522a for(e = &p[n]; p < e; p += DIRLEN) mntdirfix(p, c); . 513,521c n = mntrdwr(Tread, c, buf, n, offset); if((c->qid.path & CHDIR) == 0) return n; . 510a n = mntrdwr(Tread, c, p, n, offset); cupdate(c, p, n, offset); return n + nc; . 508c p += nc; . 499,502c p = buf; if(c->flag & CCACHE) { . 497d 495a int nc; . 490c return mnt9prdwr(Tread, c, buf, n, offset); . 47c long mntrdwr(int , Chan*, void*,long , ulong); long mnt9prdwr(int , Chan*, void*,long , ulong); . ## diffname port/devmnt.c 1995/0202 ## diff -e /n/fornaxdump/1995/0129/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0202/sys/src/brazil/port/devmnt.c 180c * If CHDIR is clear in the returned qid, the foreign server is . ## diffname port/devmnt.c 1995/0204 ## diff -e /n/fornaxdump/1995/0202/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0204/sys/src/brazil/port/devmnt.c 598a if(c->path & CHDIR) cache = 0; . 519,521d 516,517c if(isdir) { for(e = &p[n]; p < e; p += DIRLEN) mntdirfix(p, c); } . 501c if(cache) { . 499a isdir = 0; cache = c->flag & CCACHE; if(c->qid.path & CHDIR) { cache = 0; isdir = 1; } . 498a int nc, cache, isdir; . 497d ## diffname port/devmnt.c 1995/0206 ## diff -e /n/fornaxdump/1995/0204/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0206/sys/src/brazil/port/devmnt.c 605c if(c->qid.path & CHDIR) . ## diffname port/devmnt.c 1995/0508 ## diff -e /n/fornaxdump/1995/0206/sys/src/brazil/port/devmnt.c /n/fornaxdump/1995/0508/sys/src/brazil/port/devmnt.c 142,143c if(strncmp(bogus.spec, "mntblk=", 7) == 0) { m->blocksize = strtoul(bogus.spec+7, 0, 0); if(m->blocksize > MAXFDATA) m->blocksize = MAXFDATA; print("mount blk %d\n", m->blocksize); . ## diffname port/devmnt.c 1996/0223 ## diff -e /n/fornaxdump/1995/0508/sys/src/brazil/port/devmnt.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devmnt.c 7d ## diffname port/devmnt.c 1996/0510 ## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devmnt.c /n/fornaxdump/1996/0510/sys/src/brazil/port/devmnt.c 778a splx(x); . 773a splx(x); . 770a x = splhi(); /* because sleep also does */ . 765a int x; . ## diffname port/devmnt.c 1997/0220 ## diff -e /n/fornaxdump/1996/0510/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/0220/sys/src/brazil/port/devmnt.c 771,783c if(q->done == 0) if(wakeup(&q->r)) break; . ## diffname port/devmnt.c 1997/0327 ## diff -e /n/emeliedump/1997/0220/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/0327/sys/src/brazil/port/devmnt.c 1081a Dev mntdevtab = { mntreset, devinit, mntattach, mntclone, mntwalk, mntstat, mntopen, mntcreate, mntclose, mntread, devbread, mntwrite, devbwrite, mntremove, mntwstat, }; . 1072c cclose(m->c); . 944c Mnt* . 859a new->flushtag = 0; . 838c Mntrpc* . 831c l = devtab[m->c->type]->write(m->c, r->flush, n, 0); . 823a if(n < 0) panic("bad message type in mntflush"); . 766d 752c n = devtab[m->c->type]->read(m->c, r->rpc, MAXRPC, 0); . 741,742c mntgate(m); . 702,706d 697c if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) . 687a if(n < 0) panic("bad message type in mountio"); . 552,557d 545c static long . 533,538d 496c static long . 470c static void . 464c static void . 458c static void . 434c cclose(m->c); . 395c static void . 366c static void . 336c static Chan* . 314c static void . 285c static int . 266c cclose(nc); . 250c static Chan* . 152,159d 75,80c static Chan* . 66c static void . 46,47c long mntrdwr(int, Chan*, void*, long, ulong); long mnt9prdwr(int, Chan*, void*, long, ulong); . 37c void mntauth(Mnt*, Mntrpc*, char*, ushort); . ## diffname port/devmnt.c 1997/0405 ## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/0405/sys/src/brazil/port/devmnt.c 642c print("mnt: proc %s %d: mismatch rep 0x%lux T%d R%d rq %d fls %d rp %d\n", up->text, up->pid, . ## diffname port/devmnt.c 1997/0408 ## diff -e /n/emeliedump/1997/0405/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/0408/sys/src/brazil/port/devmnt.c 1057a 'm', "mnt", . 943,944c int r; r = devtab[c->type]->dc; dirbuf[DIRLEN-4] = r>>0; dirbuf[DIRLEN-3] = r>>8; . 721c if(devtab[m->c->type]->dc == L'M') . 671c if(devtab[m->c->type]->dc == L'M'){ . ## diffname port/devmnt.c 1997/0409 ## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/0409/sys/src/brazil/port/devmnt.c 1061c 'M', . ## diffname port/devmnt.c 1997/1104 ## diff -e /n/emeliedump/1997/0409/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/1104/sys/src/brazil/port/devmnt.c 702a poot("M2", m->c->qid.path); . 698a poot("M1", m->c->qid.path); . ## diffname port/devmnt.c 1997/1105 ## diff -e /n/emeliedump/1997/1104/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/1105/sys/src/brazil/port/devmnt.c 704d 699d ## diffname port/devmnt.c 1997/1205 ## diff -e /n/emeliedump/1997/1105/sys/src/brazil/port/devmnt.c /n/emeliedump/1997/1205/sys/src/brazil/port/devmnt.c 130a lock(m); . 128d 97a unlock(&mntalloc); . 95d ## diffname port/devmnt.c 1998/0319 ## diff -e /n/emeliedump/1997/1205/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0319/sys/src/brazil/port/devmnt.c 528a ulong offset = off; . 527c mntwrite(Chan *c, void *buf, long n, vlong off) . 487a ulong offset = off; . 484c mntread(Chan *c, void *buf, long n, vlong off) . ## diffname port/devmnt.c 1998/0327 ## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0327/sys/src/brazil/port/devmnt.c 610c off += nr; . 606c cwrite(c, (uchar*)uba, nr, off); . 595c r->request.offset = off; . 573c mntrdwr(int type, Chan *c, void *buf, long n, vlong off) . 556c r->request.offset = off; . 536c mnt9prdwr(int type, Chan *c, void *buf, long n, vlong off) . 530,532c return mntrdwr(Twrite, c, buf, n, off); . 524c return mnt9prdwr(Twrite, c, buf, n, off); . 522c mntwrite9p(Chan *c, void *buf, long n, vlong off) . 512c n = mntrdwr(Tread, c, buf, n, off); . 507,508c n = mntrdwr(Tread, c, p, n, off); cupdate(c, p, n, off); . 505c off += nc; . 499c nc = cread(c, buf, n, off); . 488d 480c return mnt9prdwr(Tread, c, buf, n, off); . 478c mntread9p(Chan *c, void *buf, long n, vlong off) . 46,47c long mntrdwr(int, Chan*, void*, long, vlong); long mnt9prdwr(int, Chan*, void*, long, vlong); . ## diffname port/devmnt.c 1998/0512 ## diff -e /n/emeliedump/1998/0327/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0512/sys/src/brazil/port/devmnt.c 644c r, r->request.type, r->reply.type, r->request.tag, . 526c static long . 520c long . 483c static long . 477c long . 451c static void . 387c . 382c static void . 353c static void . 301c static void . 272c static int . 115c mntalloc.mntfree = m->list; . 109c unlock(m); . ## diffname port/devmnt.c 1998/0724 ## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0724/sys/src/brazil/port/devmnt.c 1057a cclose(c2); . 1049c c2 = m->c; . 1027c Chan *c1, *c2; . ## diffname port/devmnt.c 1998/0825 ## diff -e /n/emeliedump/1998/0724/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0825/sys/src/brazil/port/devmnt.c 642c print("mnt: proc %s %lud: mismatch rep 0x%lux T%d R%d rq %d fls %d rp %d\n", . 149c sprint(buf, "#M%lud", m->id); . ## diffname port/devmnt.c 1998/0829 ## diff -e /n/emeliedump/1998/0825/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0829/sys/src/brazil/port/devmnt.c 896c mattach(m, c, c->xmh->mount->spec); . ## diffname port/devmnt.c 1998/0908 ## diff -e /n/emeliedump/1998/0829/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0908/sys/src/brazil/port/devmnt.c 611c if(nr != nreq || n == 0 || up->nnote) . 597,598c if(nr > nreq) nr = nreq; . 595a nreq = r->request.count; . 576c ulong cnt, nr, nreq; . ## diffname port/devmnt.c 1998/0916 ## diff -e /n/emeliedump/1998/0908/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0916/sys/src/brazil/port/devmnt.c 771a } . 770c }else { if(mntstats != nil) (*mntstats)(r->request.type, m->c, q->stime); . 768a if(mntstats != nil) (*mntstats)(q->request.type, m->c, q->stime); . 678a r->stime = fastticks(nil); r->bytes = n; . 57a extern void (*mntstats)(int, Chan*, uvlong); . 13a uvlong stime; /* start time */ . ## diffname port/devmnt.c 1998/0917 ## diff -e /n/emeliedump/1998/0916/sys/src/brazil/port/devmnt.c /n/emeliedump/1998/0917/sys/src/brazil/port/devmnt.c 778c (*mntstats)(r->request.type, m->c, r->stime, r->reqlen + r->replen); . 774c (*mntstats)(q->request.type, m->c, q->stime, q->reqlen + r->replen); . 767a /* trade pointers to receive buffer */ . 733a r->replen = n; . 682c r->reqlen = n; . 59c void (*mntstats)(int, Chan*, uvlong, ulong); . 21a uvlong stime; /* start time for mnt statistics */ ulong reqlen; /* request length for mnt statistics */ ulong replen; /* reply length for mnt statistics */ . 14d ## diffname port/devmnt.c 1999/0212 ## diff -e /n/emeliedump/1998/0917/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/0212/sys/src/brazil/port/devmnt.c 857,858c if(mntalloc.nrpcfree >= 10){ free(r->rpc); free(r); } else{ r->list = mntalloc.rpcfree; mntalloc.rpcfree = r; mntalloc.nrpcfree++; } mntalloc.nrpcused--; . 844a else { mntalloc.rpcfree = new->list; mntalloc.nrpcfree--; } mntalloc.nrpcused++; . 842d 839a exhausted("mount rpc header"); } /* * The header is split from the data buffer as * mountmux may swap the buffer with another header. */ new->rpc = mallocz(MAXRPC, 0); if(new->rpc == nil){ free(new); unlock(&mntalloc); . 834,838c if(new == nil){ new = malloc(sizeof(Mntrpc)); if(new == nil) { . 783c (*mntstats)(r->request.type, m->c, r->stime, . 778,779c (*mntstats)(q->request.type, m->c, q->stime, q->reqlen + r->replen); . 770,771c if(q != r) { /* * Completed someone else. * Trade pointers to receive buffer. */ . 31a int nrpcfree; int nrpcused; . ## diffname port/devmnt.c 1999/0320 ## diff -e /n/emeliedump/1999/0212/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/0320/sys/src/brazil/port/devmnt.c 1003a Mnt *m; m = v; . 1002c recdone(void *v) . 997a Mntrpc *r; r = v; . 996c rpcattn(void *v) . 57c int rpcattn(void*); . ## diffname port/devmnt.c 1999/0629 ## diff -e /n/emeliedump/1999/0320/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/0629/sys/src/brazil/port/devmnt.c 1107a #endif . 1072a panic("mntrepl"); #ifdef asdf . 1042c panic("mntrecover\n"); // rootrecover(m->c->path, m->tree.root->elem); . 958a #endif . 911a panic("recoverchan"); #ifdef asdf BUG: WON'T WORK WITH PATHS GONE? . 418,420d 300,301d 297,298d 282d 236,237d 187,188d 156d ## diffname port/devmnt.c 1999/0714 ## diff -e /n/emeliedump/1999/0629/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/0714/sys/src/brazil/port/devmnt.c 1063c mntrepl(char*) . 897c recoverchan(Mnt*, Chan*) . 401c mclose(Mnt *m, Chan*) . ## diffname port/devmnt.c 1999/0722 ## diff -e /n/emeliedump/1999/0714/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/0722/sys/src/brazil/port/devmnt.c 587c if(n > m->blocksize){ if(c->qid.path & CHDIR) r->request.count = (m->blocksize/DIRLEN)*DIRLEN; else r->request.count = m->blocksize; } else r->request.count = n; . 39d ## diffname port/devmnt.c 1999/1018 ## diff -e /n/emeliedump/1999/0722/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/1018/sys/src/brazil/port/devmnt.c 643c r, r->request.tag, r->request.fid, r->request.type, r->reply.type, . 641c print("mnt: proc %s %lud: mismatch rep 0x%lux tag %d fid %d T%d R%d fls %d rp %d\n", . ## diffname port/devmnt.c 1999/1105 ## diff -e /n/emeliedump/1999/1018/sys/src/brazil/port/devmnt.c /n/emeliedump/1999/1105/sys/src/9/port/devmnt.c 998,1107d 970,975d 901,956d 630d 624,628d 58d ## diffname port/devmnt.c 1999/1109 ## diff -e /n/emeliedump/1999/1105/sys/src/9/port/devmnt.c /n/emeliedump/1999/1109/sys/src/9/port/devmnt.c 148c m->blocksize = MAXFDATA; . 60d 38,39d ## diffname port/devmnt.c 1999/1230 ## diff -e /n/emeliedump/1999/1109/sys/src/9/port/devmnt.c /n/emeliedump/1999/1230/sys/src/9/port/devmnt.c 789a if(r->done){ unlock(m); return 1; } . 763d 752a q->done = 1; . 750,751c if((q->flushed==0 && q->request.tag == r->reply.tag) || (q->flushed && q->flushtag == r->reply.tag)) { . ## diffname port/devmnt.c 2000/0101 ## diff -e /n/emeliedump/1999/1230/sys/src/9/port/devmnt.c /n/emeliedump/2000/0101/sys/src/9/port/devmnt.c 775a if(mntstats != nil) (*mntstats)(q->request.type, m->c, q->stime, q->reqlen + r->replen); if(q != r) wakeup(&q->r); . 764,774d ## diffname port/devmnt.c 2000/0102 ## diff -e /n/emeliedump/2000/0101/sys/src/9/port/devmnt.c /n/emeliedump/2000/0102/sys/src/9/port/devmnt.c 764a q->done = 1; unlock(m); . 753,754d 618c r->reply.type = Tmax; /* can't ever be a valid message type */ . ## diffname port/devmnt.c 2000/0104 ## diff -e /n/emeliedump/2000/0102/sys/src/9/port/devmnt.c /n/emeliedump/2000/0104/sys/src/9/port/devmnt.c 877d 848,849d 808,812d 806d 802,804c mountio(m, fr); mntfree(fr); if(!r->done){ r->reply.type = Rflush; . 795,800c fr->request.type = Tflush; if(r->request.type == Tflush) fr->request.oldtag = r->request.oldtag; else fr->request.oldtag = r->request.tag; . 784,793c fr = mntralloc(0); . 781,782c Mntrpc *fr; . 778c void . 750,751c // look for a reply to a message if(q->request.tag == r->reply.tag) { . 716d 703,709d 694a poperror(); . 686a } . 684,685c if(r->done){ poperror(); . 678,682d 670a r->stime = fastticks(nil); r->reqlen = n; . 659,669c if(devtab[m->c->type]->dc == L'M'){ if(mnt9prdwr(Twrite, m->c, r->rpc, n, 0) != n) error(Emountrpc); }else{ if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) error(Emountrpc); . 657a mntflush(m, r); return; . 656c if(m->rip == up) mntgate(m); if(strcmp(up->error, Eintr) != 0) . 645d 634c r->reply.tag); . 631c print("mnt: proc %s %lud: mismatch rep 0x%lux tag %d fid %d T%d R%d rp %d\n", . 405d 123,124d 63,64d 42c void mntflush(Mnt*, Mntrpc*); . 18,20d ## diffname port/devmnt.c 2000/0105 ## diff -e /n/emeliedump/2000/0104/sys/src/9/port/devmnt.c /n/emeliedump/2000/0105/sys/src/9/port/devmnt.c 813a new->flushed = nil; . 775,777c /* * Free a chain of flushes. Remove each unanswered * flush and the original message from the unanswered * request queue. Mark the original message as done * and if it hasn't been answered set the reply to to * Rflush. */ void mntflushfree(Mnt *m, Mntrpc *r) { Mntrpc *fr; while(r){ fr = r->flushed; if(!r->done){ r->reply.type = Rflush; mntqrm(m, r); } if(fr) mntfree(r); r = fr; . 772,773c return fr; } . 770a fr->flushed = r; . 759,760c /* * Create a new flush request and chain the previous * requests from it */ Mntrpc* mntflushalloc(Mntrpc *r) . 731c /* look for a reply to a message */ . 683a mntflushfree(m, r); . 672a mntflushfree(m, r); . 646,653d 635a while(waserror()) { if(m->rip == up) mntgate(m); if(strcmp(up->error, Eintr) != 0){ mntflushfree(m, r); nexterror(); } r = mntflushalloc(r); } . 39c Mntrpc* mntflushalloc(Mntrpc*); void mntflushfree(Mnt*, Mntrpc*); . 20a Mntrpc* flushed; /* message this one flushes */ . ## diffname port/devmnt.c 2001/0503 ## diff -e /n/emeliedump/2000/0105/sys/src/9/port/devmnt.c /n/emeliedump/2001/0503/sys/src/9/port/devmnt.c 911c static int . 899c static void . 883c static Mnt* . 864c static void . 847c static void . 810c static Mntrpc* . 793c static void . 769c static Mntrpc* . 728c static void . 713c static void . 692c static void . 633c static void . 625,628c sn = "?"; if(m->c->name != nil) sn = m->c->name->s; cn = "?"; if(r->c != nil && r->c->name != nil) cn = r->c->name->s; print("mnt: proc %s %lud: mismatch from %s %s rep 0x%lux tag %d fid %d T%d R%d rp %d\n", up->text, up->pid, sn, cn, r, r->request.tag, r->request.fid, r->request.type, r->reply.type, r->reply.tag); . 608a char *sn, *cn; . 606c static void . 551c static long . 514c static long . 407c static void . 390c static void . 223a authreply(m->c->session, id, &r->reply); . 219a c->type = devno('M', 0); . 218d 198c static void . 190c c = devattach('/', 0); . 185c /* * start off the channel as a root device * until we've really gotten it started so * an early close won't run through devmnt again */ static Chan* . 152,155c cclose(c); . 98c cclose(c); . 36,55c static void mattach(Mnt*, Chan*, char*); static void mntauth(Mnt*, Mntrpc*, char*, ushort); static Mnt* mntchk(Chan*); static void mntdirfix(uchar*, Chan*); static Mntrpc* mntflushalloc(Mntrpc*); static void mntflushfree(Mnt*, Mntrpc*); static void mntfree(Mntrpc*); static void mntgate(Mnt*); static void mntpntfree(Mnt*); static void mntqrm(Mnt*, Mntrpc*); static Mntrpc* mntralloc(Chan*); static long mntrdwr(int, Chan*, void*, long, vlong); static long mnt9prdwr(int, Chan*, void*, long, vlong); static void mntrpcread(Mnt*, Mntrpc*); static void mountio(Mnt*, Mntrpc*); static void mountmux(Mnt*, Mntrpc*); static void mountrpc(Mnt*, Mntrpc*); static int rpcattn(void*); static void mclose(Mnt*, Chan*); static Chan* mntchan(void); . ## diffname port/devmnt.c 2001/0527 ## diff -e /n/emeliedump/2001/0503/sys/src/9/port/devmnt.c /n/emeliedump/2001/0527/sys/src/9/port/devmnt.c 938d 922c int . 916,919c dirbuf += BIT16SZ; /* skip count */ PBIT16(dirbuf, r); dirbuf += BIT16SZ; PBIT32(dirbuf, c->dev); . 913c uint r; . 910c /* * Rewrite channel type and dev for in-flight data to * reflect local values. These entries are known to be * the first two in the Dir encoding after the count. */ void . 894c Mnt* . 875c void . 858c void . 838c new->rpc = mallocz(iounit, 0); . 821,822c Mntrpc* mntralloc(Chan *c, ulong iounit) . 804c void . 785c fr = mntralloc(0, iounit); . 780,781c Mntrpc* mntflushalloc(Mntrpc *r, ulong iounit) . 773a print("unexpected reply tag %ud; type %d\n", r->reply.tag, r->reply.type); . 742c uchar *dp; . 739c void . 724c void . 721a return 0; . 718,720c r->replen = n; if(convM2S(r->rpc, n, &r->reply) == 0){ int i; print("bad conversion of received message; %d bytes iounit %ld\n", n, m->c->iounit); for(i=0; irpc[i]); print("\n"); return -1; . 708,716c chunk = m->c->iounit; if(chunk == 0 || chunk > m->c->iounit) chunk = m->c->iounit; r->reply.type = 0; r->reply.tag = 0; /* read size, then read exactly the right number of bytes */ n = mntreadn(m->c, r->rpc, BIT32SZ); if(n != BIT32SZ){ if(n > 0) print("devmnt expected BIT32SZ got %d\n", n); return -1; } len = GBIT32((uchar*)r->rpc); if(len <= BIT32SZ || len > chunk){ print("devmnt: len %d max messagesize %ld\n", len, m->c->iounit); return -1; } n += mntreadn(m->c, r->rpc+BIT32SZ, len-BIT32SZ); if(n != len){ print("devmnt: length %d expected %d\n", n, len); return -1; } . 706c int n, len; ulong chunk; . 703c int mntreadn(Chan *c, uchar *buf, int n) { int m, dm; for(m=0; mtype]->read(c, buf, n-m, 0); if(dm <= 0) return 0; buf += dm; } return n; } int . 695c if(mntrpcread(m, r) < 0) error(Emountrpc); . 669,675c if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) error(Emountrpc); . 666c if(m->c->iounit == 0) panic("iounit"); n = convS2M(&r->request, r->rpc, m->c->iounit); . 656c r = mntflushalloc(r, m->c->iounit); . 644c void . 610c void . 580,586c nr = n; if(nr > m->c->iounit-IOHDRSZ) nr = m->c->iounit-IOHDRSZ; if(c->iounit != 0 && nr > c->iounit) nr = c->iounit; r->request.count = nr; . 571c r = mntralloc(c, m->c->iounit); . 568c if(c->qid.type & QTDIR) . 518,555c long . 506,511d 500a } if(p != e) error(Esbadstat); . 499c for(e = &p[n]; p+BIT16SZ < e; p += dirlen){ dirlen = BIT16SZ+GBIT16(p); if(p+dirlen > e) break; validstat(p, dirlen); . 477c if(c->qid.type & QTDIR) { . 473c int nc, cache, isdir, dirlen; . 463,468d 460a return n; . 457c r->request.nstat = n; r->request.stat = dp; . 450c r = mntralloc(c, m->c->iounit); . 443,444c static int mntwstat(Chan *c, uchar *dp, int n) . 411c void . 394c void . 379c r = mntralloc(c, m->c->iounit); . 346,369c mntopencreate(Tcreate, c, name, omode, perm); . 342a static Chan* mntopen(Chan *c, int omode) { return mntopencreate(Topen, c, nil, omode, 0); } . 332a c->iounit = r->reply.iounit; . 327a if(type == Tcreate){ r->request.perm = perm; r->request.name = name; } . 325c r->request.type = type; . 320c r = mntralloc(c, m->c->iounit); . 314c mntopencreate(int type, Chan *c, char *name, int omode, ulong perm) . 310a return n; . 307,308c if(r->reply.nstat >= 1<<(8*BIT16SZ)) error("returned stat buffer count too large"); if(r->reply.nstat > n){ /* doesn't fit; just patch the count and return */ PBIT16((uchar*)dp, r->reply.nstat); n = BIT16SZ; }else{ n = r->reply.nstat; memmove(dp, r->reply.stat, n); validstat(dp, n); mntdirfix(dp, c); } . 298c r = mntralloc(c, m->c->iounit); . 296a if(n < BIT16SZ) error(Eshortstat); . 291,292c static int mntstat(Chan *c, uchar *dp, int n) . 288c poperror(); return wq; . 284,285c Return: . 279,282c wq->nqid = r->reply.nwqid; for(i=0; inqid; i++) wq->qid[i] = r->reply.wqid[i]; . 261,277c /* move new fid onto mnt device and update its qid */ if(wq->clone != nil){ if(wq->clone != c){ wq->clone->type = c->type; incref(m); } if(r->reply.nwqid > 0) wq->clone->qid = r->reply.wqid[r->reply.nwqid-1]; . 257,259c if(r->reply.nwqid > nname) error("too many QIDs returned by walk"); if(r->reply.nwqid < nname){ if(alloc) cclose(nc); wq->clone = nil; if(r->reply.nwqid == 0){ free(wq); wq = nil; goto Return; } } . 254a r->request.nwname = nname; memmove(r->request.wname, name, nname*sizeof(char*)); . 251,252c r->request.type = Twalk; . 249a return nil; . 247,248d 244a wq->clone = nc; . 240,242c r = mntralloc(c, m->c->iounit); if(nc == nil){ nc = devclone(c); /* * Until the other side accepts this fid, we can't mntclose it. * Therefore set type to 0 for now; rootclose is known to be safe. */ nc->type = 0; . 238a if(nname > MAXWELEM) error("devmnt: too many name elements"); alloc = 0; wq = smalloc(sizeof(Walkqid)+(nname-1)*sizeof(Qid)); if(waserror()){ if(alloc && wq->clone!=nil) cclose(wq->clone); free(wq); return nil; } alloc = 0; . 237c Walkqid *wq; extern int chandebug; if(chandebug){ print("mntwalk "); for(i=0; irequest.uname = up->user; r->request.aname = spec; r->request.nauth = 0; r->request.auth = (uchar*)""; . 206c r = mntralloc(0, m->c->iounit); . 203d 200c void . 192c c = devattach('M', 0); . 182,187c Chan* . 169c c->qid.type |= QTDIR; . 167c if(mc->type == devno('M', 0) && (c->qid.type&QTDIR) == 0) { . 161c * If QTDIR is clear in the returned qid, the foreign server is . 152c /* Close must not be called since it will * call mnt recursively */ chanfree(c); . 145,146d 132,140c if(m->c->iounit == 0) m->c->iounit = MAXRPC; . 98c chanfree(c); . 78d 68a fmtinstall('F', fcallconv); fmtinstall('D', dirconv); fmtinstall('M', dirmodeconv); . 56a char Esbadstat[] = "invalid directory entry received from server"; . 36,55c void mattach(Mnt*, Chan*, char*); void mntauth(Mnt*, Mntrpc*, char*, ushort); Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); Mntrpc* mntflushalloc(Mntrpc*, ulong); void mntflushfree(Mnt*, Mntrpc*); void mntfree(Mntrpc*); void mntgate(Mnt*); void mntpntfree(Mnt*); void mntqrm(Mnt*, Mntrpc*); Mntrpc* mntralloc(Chan*, ulong); long mntrdwr(int, Chan*, void*, long, vlong); int mntrpcread(Mnt*, Mntrpc*); void mountio(Mnt*, Mntrpc*); void mountmux(Mnt*, Mntrpc*); void mountrpc(Mnt*, Mntrpc*); int rpcattn(void*); void mclose(Mnt*, Chan*); Chan* mntchan(void); . 16c uchar* rpc; /* I/O Data buffer */ . 13c Fcall reply; /* Incoming reply */ . 7a #define MAXRPC (IOHDRSZ+8192) . ## diffname port/devmnt.c 2001/0601 ## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devmnt.c /n/emeliedump/2001/0601/sys/src/9/port/devmnt.c 717c n += mntreadn(m->c, r->rpc+BIT32SZ, len-BIT32SZ, 1); . 706c n = mntreadn(m->c, r->rpc, BIT32SZ, 0); . 686a if(uninterruptable) poperror(); . 685a if(uninterruptable) if(waserror()){ /* user DEL may stop assembly; wait for full 9P msg. */ if(strstr(up->error, "interrupt") == nil) nexterror(); dm = 0; continue; } . 681c mntreadn(Chan *c, uchar *buf, int n, int uninterruptable) . 230,231c if(0){ . 158,174d 83c Chan *c; . ## diffname port/devmnt.c 2001/0619 ## diff -e /n/emeliedump/2001/0601/sys/src/9/port/devmnt.c /n/emeliedump/2001/0619/sys/src/9/port/devmnt.c 865a if(r->b != nil) freeblist(r->b); . 859a new->b = nil; . 763a q->b = r->b; r->b = nil; . 760,762d 746d 724a /* hang the data off of the fcall struct */ l = &r->b; *l = nil; do { b = qremove(m->q); if(hlen > 0){ b->rp += hlen; len -= hlen; hlen = 0; } i = BLEN(b); if(i <= len){ len -= i; *l = b; l = &(b->next); } else { /* split block and put unused bit back */ nb = allocb(i-len); memmove(nb->wp, b->rp+len, i-len); b->wp = b->rp+len; nb->wp += i-len; qputback(m->q, nb); *l = b; return 0; } }while(len > 0); . 716,722c if(convM2S(nb->rp, len, &r->reply) <= 0){ /* bad message, dump it */ print("mntrpcread: convM2S failed\n"); qdiscard(m->q, len); . 714a nb = pullupqueue(m->q, hlen); . 710,713c /* pullup the header (i.e. everything except data) */ t = nb->rp[BIT32SZ]; switch(t){ case Rread: hlen = BIT32SZ+BIT8SZ+BIT16SZ+BIT32SZ; break; default: hlen = len; break; . 705,708c nb = pullupqueue(m->q, BIT32SZ+BIT8SZ+BIT16SZ); len = GBIT32(nb->rp); /* read in the rest of the message */ while(qlen(m->q) < len){ b = devtab[m->c->type]->bread(m->c, 2*MAXRPC, 0); if(b == nil) return -1; qadd(m->q, b); . 698,703c /* read at least length, type, and tag and pullup to a single block */ while(qlen(m->q) < BIT32SZ+BIT8SZ+BIT16SZ){ b = devtab[m->c->type]->bread(m->c, 2*MAXRPC, 0); if(b == nil) return -1; qadd(m->q, b); . 693,695d 690,691c int i, t, len, hlen; Block *b, **l, *nb; . 664,687d 556c r->b = bl2mem((uchar*)uba, r->b, nr); . 431a qfree(q); . 430a q = m->q; . 428d 417a Queue *q; . 214,220d 128a m->q = qopen(10*MAXRPC, 0, nil, nil); . 18a Block *b; /* reply blocks */ . 15c Fcall reply; /* Incoming reply */ . ## diffname port/devmnt.c 2001/0807 ## diff -e /n/emeliedump/2001/0619/sys/src/9/port/devmnt.c /n/emeliedump/2001/0807/sys/src/9/port/devmnt.c 460a poperror(); mntfree(r); return n; } int mntauth(Chan *c, uchar *auth, int nauth, uchar *rauth, int nrauth) { int n; Mnt *m; Mntrpc *r; m = mntchk(c); r = mntralloc(c, m->c->iounit); if(waserror()) { mntfree(r); nexterror(); } r->request.type = Tauth; r->request.fid = c->fid; r->request.nauth = nauth; r->request.auth = auth; mountrpc(m, r); n = r->reply.nrauth; if(nrauth < n) error(Eshort); memmove(rauth, r->reply.rauth, n); . 196,197d 40d ## diffname port/devmnt.c 2001/0808 ## diff -e /n/emeliedump/2001/0807/sys/src/9/port/devmnt.c /n/emeliedump/2001/0808/sys/src/9/port/devmnt.c 458,484d 194a r->request.nauth = 0; r->request.auth = (uchar*)""; . 39a void mntauth(Mnt*, Mntrpc*, char*, ushort); . ## diffname port/devmnt.c 2001/0819 ## diff -e /n/emeliedump/2001/0808/sys/src/9/port/devmnt.c /n/emeliedump/2001/0819/sys/src/9/port/devmnt.c 920c panic("mntchk 3: can't happen"); . 917c * Was it closed and reused (was error(Eshutdown); now, it can't happen) . 915a if(c->mchan == nil) panic("mntchk 1: nil mchan c %s\n", c2name(c)); m = c->mchan->mux; if(m == nil) print("mntchk 2: nil mux c %s c->mchan %s \n", c2name(c), c2name(c->mchan)); . 914c /* This routine is mostly vestiges of prior lives; now it's just sanity checking */ . 860a if(new->rpclen < iounit){ free(new->rpc); new->rpc = mallocz(iounit, 0); if(new->rpc == nil){ free(new); mntalloc.nrpcused--; unlock(&mntalloc); exhausted("mount rpc buffer"); } new->rpclen = iounit; } . 855a new->rpclen = iounit; . 405d 397,399d 393c muxclose(Mnt *m) . 388d 380d 271c wq->clone->mchan = c->mchan; incref(c->mchan); . 215a if(nc != nil) print("mntwalk: nc != nil\n"); . 207a Chan* mntchan(void) { Chan *c; c = devattach('M', 0); lock(&mntalloc); c->dev = mntalloc.id++; unlock(&mntalloc); if(c->mchan) panic("mntchan non-zero %p", c->mchan); return c; } . 205a poperror(); /* c */ if(bogus.flags&MCACHE) c->flag |= CCACHE; return c; . 204c poperror(); /* r */ . 201a incref(m->c); . 195,197c r->request.aname = bogus.spec; . 193a if(bogus.authchan == nil) r->request.afid = NOFID; else r->request.afid = bogus.authchan->fid; . 185d 183a bogus = *((struct bogus *)muxattach); c = bogus.chan; m = c->mux; if(m == nil){ mntversion(c, nil, 0, 0); m = c->mux; if(m == nil) error(Enoversion); } c = mntchan(); if(waserror()) { /* Close must not be called since it will * call mnt recursively */ chanfree(c); nexterror(); } . 182a struct bogus{ Chan *chan; Chan *authchan; char *spec; int flags; }bogus; . 181a Mnt *m; Chan *c; . 179,180c static Chan* mntattach(char *muxattach) . 176a . 175a poperror(); /* c */ . 171,174c poperror(); /* r */ mntfree(r); . 166,169c c->qid = r->reply.aqid; c->mchan = m->c; incref(m->c); c->mqid = c->qid; c->mode = ORDWR; . 163,164c r->request.type = Tauth; r->request.afid = c->fid; r->request.uname = up->user; r->request.aname = spec; mountrpc(m, r); . 160,161c if(waserror()) { mntfree(r); nexterror(); } . 157,158c r = mntralloc(0, m->c->iounit); . 149d 146a return k; } Chan* mntauth(Chan *c, char *spec) { Mnt *m; Mntrpc *r; m = c->mux; if(m == nil){ mntversion(c, VERSION9P, MAXRPC, 0); m = c->mux; if(m == nil) error(Enoversion); } . 145c k = strlen(f.version); if(returnlen > 0){ if(returnlen < k) error(Eshort); memmove(version, f.version, k); } . 143c poperror(); /* c */ qunlock(&c->umqlock); . 138,141c unlock(m); . 136a c->flag |= CMSG; c->mux = m; . 134d 132a poperror(); /* msg */ free(msg); . 128a kstrdup(&m->version, f.version); . 116a f.type = Tversion; f.tag = NOTAG; f.msize = msize; f.version = v; msg = malloc(8192+IOHDRSZ); if(msg == nil) exhausted("version memory"); if(waserror()){ free(msg); nexterror(); } k = convS2M(&f, msg, 8192+IOHDRSZ); if(k == 0) error("bad fversion conversion on send"); lock(c); oo = c->offset; c->offset += k; unlock(c); l = devtab[c->type]->write(c, msg, k, oo); if(l < k){ lock(c); c->offset -= k - l; unlock(c); error("short write in fversion"); } /* message sent; receive and decode reply */ k = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); if(k <= 0) error("EOF receiving fversion reply"); lock(c); c->offset += k; unlock(c); l = convM2S(msg, k, &f); if(l != k) error("bad fversion conversion on reply"); if(f.type != Rversion) error("unexpected reply type in fversion"); if(f.msize > msize) error("server tries to increase msize in fversion"); if(f.msize<256 || f.msize>1024*1024) error("nonsense value of msize in fversion"); if(strncmp(f.version, v, strlen(f.version)) != 0) error("bad 9P version returned from server"); c->iounit = f.msize; if(c->iounit == 0) c->iounit = MAXRPC; /* now build Mnt associated with this connection */ lock(&mntalloc); . 114a if(returnlen > 0){ if(returnlen < k) error(Eshort); memmove(version, buf, k); } return k; . 94,113c /* defaults */ if(msize == 0) msize = MAXRPC-IOHDRSZ; v = version; if(v == nil || v[0] == '\0') v = VERSION9P; /* validity */ if(msize < 0) error("bad iounit in version call"); if(strncmp(v, VERSION9P, strlen(VERSION9P)) != 0) error("bad 9P version specification"); m = c->mux; if(m != nil){ qunlock(&c->umqlock); poperror(); strecpy(buf, buf+sizeof buf, m->version); k = strlen(buf); if(strncmp(buf, v, k) != 0){ snprint(buf, sizeof buf, "incompatible 9P versions %s %s", m->version, v); error(buf); . 91,92c qlock(&c->umqlock); /* make sure no one else does this until we've established ourselves */ if(waserror()){ qunlock(&c->umqlock); nexterror(); } . 84,89c char *v; long k, l; uvlong oo; char buf[128]; . 82a Fcall f; uchar *msg; . 80,81c /* * Version is not multiplexed: message sent only once per connection. */ long mntversion(Chan *c, char *version, int msize, int returnlen) . 59a char Enoversion[] = "version not established for mount channel"; . 56d 40d 18a uint rpclen; /* len of buffer */ . 7a /* * References are managed as follows: * The channel to the server - a network connection or pipe - has one * reference for every Chan open on the server. The server channel has * c->mux set to the Mnt used for muxing control to that server. Mnts * have no reference count; they go away when c goes away. * Each channel derived from the mount point has mchan set to c, * and increfs/decrefs mchan to manage references on the server * connection. */ . ## diffname port/devmnt.c 2001/0820 ## diff -e /n/emeliedump/2001/0819/sys/src/9/port/devmnt.c /n/emeliedump/2001/0820/sys/src/9/port/devmnt.c 1034c new->rpclen = msize; . 1027c new->rpc = mallocz(msize, 0); . 1025c if(new->rpclen < msize){ . 1019c new->rpclen = msize; . 1013c new->rpc = mallocz(msize, 0); . 997c mntralloc(Chan *c, ulong msize) . 789,791c if(m->msize == 0) panic("msize"); n = convS2M(&r->request, r->rpc, m->msize); . 779c r = mntflushalloc(r, m->msize); . 705,708c if(nr > m->msize-IOHDRSZ) nr = m->msize-IOHDRSZ; . 695c r = mntralloc(c, m->msize); . 614c r = mntralloc(c, m->msize); . 568a free(m->version); m->version = nil; . 546c r = mntralloc(c, m->msize); . 516a if(c->iounit > m->msize-IOHDRSZ) c->iounit = m->msize-IOHDRSZ; . 499c r = mntralloc(c, m->msize); . 465c r = mntralloc(c, m->msize); . 397c r = mntralloc(c, m->msize); . 327c r = mntralloc(0, m->msize); . 265c r = mntralloc(0, m->msize); . 213a m->msize = f.msize; . 210a m->version = nil; . 193,195d 113c msize = MAXRPC; if(msize > c->iounit && c->iounit != 0) msize = c->iounit; . ## diffname port/devmnt.c 2001/0822 ## diff -e /n/emeliedump/2001/0820/sys/src/9/port/devmnt.c /n/emeliedump/2001/0822/sys/src/9/port/devmnt.c 413d ## diffname port/devmnt.c 2001/0825 ## diff -e /n/emeliedump/2001/0822/sys/src/9/port/devmnt.c /n/emeliedump/2001/0825/sys/src/9/port/devmnt.c 850c qaddlist(m->q, b); . 840c qaddlist(m->q, b); . ## diffname port/devmnt.c 2001/0905 ## diff -e /n/emeliedump/2001/0825/sys/src/9/port/devmnt.c /n/emeliedump/2001/0905/sys/src/9/port/devmnt.c 673d ## diffname port/devmnt.c 2001/0918 ## diff -e /n/emeliedump/2001/0905/sys/src/9/port/devmnt.c /n/emeliedump/2001/0918/sys/src/9/port/devmnt.c 188a } . 187c if(f.type != Rversion){ if(f.type == Rerror) error(f.ename); . ## diffname port/devmnt.c 2001/0924 ## diff -e /n/emeliedump/2001/0918/sys/src/9/port/devmnt.c /n/emeliedump/2001/0924/sys/src/9/port/devmnt.c 779c if(strcmp(up->errstr, Eintr) != 0){ . ## diffname port/devmnt.c 2001/1206 ## diff -e /n/emeliedump/2001/0924/sys/src/9/port/devmnt.c /n/emeliedump/2001/1206/sys/src/9/port/devmnt.c 520c if(c->iounit == 0 || c->iounit > m->msize-IOHDRSZ) . ## diffname port/devmnt.c 2002/0104 ## diff -e /n/emeliedump/2001/1206/sys/src/9/port/devmnt.c /n/emeliedump/2002/0104/sys/src/9/port/devmnt.c 452a . ## diffname port/devmnt.c 2002/0109 ## diff -e /n/emeliedump/2002/0104/sys/src/9/port/devmnt.c /n/emeliedump/2002/0109/sys/src/9/port/devmnt.c 1144a devshutdown, . 453d ## diffname port/devmnt.c 2002/0217 ## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devmnt.c /n/emeliedump/2002/0217/sys/src/9/port/devmnt.c 84,86c fmtinstall('F', fcallfmt); fmtinstall('D', dirfmt); fmtinstall('M', dirmodefmt); . ## diffname port/devmnt.c 2002/0615 ## diff -e /n/emeliedump/2002/0217/sys/src/9/port/devmnt.c /n/emeliedump/2002/0615/sys/src/9/port/devmnt.c 849c b = devtab[m->c->type]->bread(m->c, m->msize, 0); . 839c b = devtab[m->c->type]->bread(m->c, m->msize, 0); . 86c /* fmtinstall('M', dirmodefmt); No! Clashes with eipfmt [sape] */ . ## diffname port/devmnt.c 2002/0919 ## diff -e /n/emeliedump/2002/0615/sys/src/9/port/devmnt.c /n/emeliedump/2002/0919/sys/src/9/port/devmnt.c 1058a freetag(r->request.tag); . 1024c new->request.tag = alloctag(); . 999a int alloctag(void) { int i, j; ulong v; for(i = 0; i < NMASK; i++){ v = mntalloc.tagmask[i]; if(v == ~0UL) continue; for(j = 0; j < 1<>TAGSHIFT] &= ~(1<<(t&TAGMASK)); } . 86c /* We can't install %M since eipfmt does and is used in the kernel [sape] */ . 83c mntalloc.tagmask[0] = 1; /* don't allow 0 as a tag */ mntalloc.tagmask[NMASK-1] = 0x80000000UL; /* don't allow NOTAG */ . 74,78d 71a . 48c ulong tagmask[NMASK]; . 38a enum { TAGSHIFT = 5, /* ulong has to be 32 bits */ TAGMASK = (1<>TAGSHIFT, }; . ## diffname port/devmnt.c 2002/1213 ## diff -e /n/emeliedump/2002/0919/sys/src/9/port/devmnt.c /n/emeliedump/2002/1213/sys/src/9/port/devmnt.c 857a if(doread(m, len) < 0) return -1; . 851,856c /* read in the rest of the message, avoid rediculous (for now) message sizes */ len = GBIT32(nb->rp); if(len > m->msize){ qdiscard(m->q, qlen(m->q)); return -1; . 849d 842,847c if(doread(m, BIT32SZ+BIT8SZ+BIT16SZ) < 0) return -1; . 831a static int doread(Mnt *m, int len) { Block *b; while(qlen(m->q) < len){ b = devtab[m->c->type]->bread(m->c, m->msize, 0); if(b == nil) return -1; if(BLEN(b) == 0){ freeblist(b); return -1; } qaddlist(m->q, b); } return 0; } . ## diffname port/devmnt.c 2003/0101 ## diff -e /n/emeliedump/2002/1213/sys/src/9/port/devmnt.c /n/emeliedump/2003/0101/sys/src/9/port/devmnt.c 484a /* * 12/31/2002 RSC * * This should be nstat-2, which is the first two * bytes of the stat buffer. But dirstat and dirfstat * depended on getting the full nstat (they didn't * add BIT16SZ themselves). I fixed dirstat and dirfstat * but am leaving this unchanged for now. After a * few months, once enough of the relevant binaries * have been recompiled for other reasons, we can * change this to nstat-2. Devstat gets this right * (via convD2M). */ . ## diffname port/devmnt.c 2003/0509 ## diff -e /n/emeliedump/2003/0101/sys/src/9/port/devmnt.c /n/emeliedump/2003/0509/sys/src/9/port/devmnt.c 1159c print("mntchk 2: nil mux c %s c->mchan %s \n", channame(c), channame(c->mchan)); . 1154c panic("mntchk 1: nil mchan c %s\n", channame(c)); .