## diffname gnot/devmnt.c 1990/03091 ## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/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 */ ulong mntid; /* serial # */ 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; 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; } 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; int i; for(m=mnt,i=0; imntid == dev){ if(m->msg == 0) break; return m; } if(noerr) return 0; error(0, Eshutdown); } 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); lock(&mntid); m->mntid = ++mntid.id; unlock(&mntid); c = devattach('M', spec); c->dev = m->mntid; 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; c->mchan = m->msg; c->mqid = c->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; nc->mchan = c->mchan; nc->mqid = c->qid; 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, *msg; int isbit; mbr = mballoc(); mbw = mballoc(); if(waserror()){ mbfree(mbr); mbfree(mbw); nexterror(); } n = convS2M(&mh->thdr, mbw->buf); isbit = 0; if(devchar[m->msg->type] == 'b') isbit = 1; /* * 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); } if(waserror()){ if(isbit) close(msg); else{ qunlock(m); qunlock(msg); } nexterror(); } 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); if(isbit) close(msg); else{ qunlock(m); qunlock(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 gnot/devmnt.c 1990/0312 ## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0312/sys/src/9/68020/devmnt.c 469a decref(m); . 384a print("close mount table %d\n", m->mntid); . ## diffname gnot/devmnt.c 1990/0324 ## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0324/sys/src/9/68020/devmnt.c 570c if(devchar[m->msg->type] == '3') . ## diffname gnot/devmnt.c 1990/0504 ## diff -e /n/bootesdump/1990/0324/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0504/sys/src/9/68020/devmnt.c 385d ## diffname gnot/devmnt.c 1990/0511 ## diff -e /n/bootesdump/1990/0504/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0511/sys/src/9/68020/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 gnot/devmnt.c 1990/05313 ## diff -e /n/bootesdump/1990/0511/sys/src/9/68020/devmnt.c /n/bootesdump/1990/05313/sys/src/9/68020/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); . 634,635c incref(q); qlock(q); qlocked = 1; . 630,632c #endif q = m->q; if(q == 0) . 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); . 585,586c print("short write in mntxmit\n"); error(0, Eshortmsg); . 566a #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) . 261a if(new) poperror(); . 258,259d 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 gnot/devmnt.c 1990/0604 ## diff -e /n/bootesdump/1990/05313/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0604/sys/src/9/68020/devmnt.c 756,758d 717,718c n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE); mqfree(q); . 709c if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){ . 706c mqfree(q); . 698,704c incref(q); . 696c if(devchar[q->msg->type] != '3') . 691c q = m->q; if(q == 0) error(0, Eshutdown); #ifdef BIT3 . ## diffname gnot/devmnt.c 1990/0605 ## diff -e /n/bootesdump/1990/0604/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0605/sys/src/9/68020/devmnt.c 656a print("err: writer\n"); . 646a print("err: reader\n"); . 169a print("mqfree\n"); . ## diffname gnot/devmnt.c 1990/0617 ## diff -e /n/bootesdump/1990/0605/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0617/sys/src/9/68020/devmnt.c 828c print("%lux interrupted i/o %d %d\n", u->p, mh->thdr.type, mh->thdr.fid); . 801c 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); . 777c print("%lux %lux %lux %d format error in mntxmit %s\n", u->p, q->reader, q->writer, n, u->p->text); . 659d 648d 290a qunlock(&mntqalloc); . 286,288c m->q = mqalloc(cm); . 274a qlock(&mntqalloc); . 170c 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 qlocked */ . 67a QLock; . ## diffname gnot/devmnt.c 1990/0619 ## diff -e /n/bootesdump/1990/0617/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0619/sys/src/9/68020/devmnt.c 856c mbfree(mh->mbr); . 836d 826c print("interrupted i/o\n"); . 818d 804,805c t = mh->mbr; mh->mbr = w->mbr; . 799c if(q->writer==0) print("response with empty queue\n"); . 773,775c 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"); . 748c mbfree(mh->mbr); . 720c if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ . 716c n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE); . 687c mbfree(mh->mbr); . 684c mh->mbr = mballoc(); . 678c Mntbuf *mbw; . 170d ## diffname gnot/devmnt.c 1990/0620 ## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0620/sys/src/9/68020/devmnt.c 824d 798d 774d ## diffname gnot/devmnt.c 1990/0703 ## diff -e /n/bootesdump/1990/0620/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0703/sys/src/9/68020/devmnt.c 849a } . 848c if(mh->thdr.type == Tread){ if(mh->rhdr.count > mh->thdr.count) error(0, Ebadcnt); . 772a poperror(); . 771a if(waserror()){ mnterrdequeue(q, mh); nexterror(); } . ## diffname gnot/devmnt.c 1990/0707 ## diff -e /n/bootesdump/1990/0703/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0707/sys/src/9/68020/devmnt.c 861a 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"); } } . ## diffname gnot/devmnt.c 1990/0717 ## diff -e /n/bootesdump/1990/0707/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0717/sys/src/9/68020/devmnt.c 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 gnot/devmnt.c 1990/0725 ## diff -e /n/bootesdump/1990/0717/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0725/sys/src/9/68020/devmnt.c 294d ## diffname gnot/devmnt.c 1990/0726 ## diff -e /n/bootesdump/1990/0725/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0726/sys/src/9/68020/devmnt.c 293a mqfree(q); . ## diffname gnot/devmnt.c 1990/0728 ## diff -e /n/bootesdump/1990/0726/sys/src/9/68020/devmnt.c /n/bootesdump/1990/0728/sys/src/9/68020/devmnt.c 294d ## diffname gnot/devmnt.c 1990/11211 ## diff -e /n/bootesdump/1990/0728/sys/src/9/68020/devmnt.c /n/bootesdump/1990/11211/sys/src/9/68020/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 gnot/devmnt.c 1990/1124 ## diff -e /n/bootesdump/1990/1123/sys/src/9/68020/devmnt.c /n/bootesdump/1990/1124/sys/src/9/68020/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 gnot/devmnt.c 1990/1126 ## diff -e /n/bootesdump/1990/1124/sys/src/9/68020/devmnt.c /n/bootesdump/1990/1126/sys/src/9/68020/devmnt.c 472d ## diffname gnot/devmnt.c 1990/1127 ## diff -e /n/bootesdump/1990/1126/sys/src/9/68020/devmnt.c /n/bootesdump/1990/1127/sys/src/9/68020/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 gnot/devmnt.c 1990/1210 # deleted ## diff -e /n/bootesdump/1990/1127/sys/src/9/68020/devmnt.c /n/bootesdump/1990/1210/sys/src/9/68020/devmnt.c 1,888d