| plan 9 kernel history: overview | file list | diff list |
1991/0904/port/devmnt.c (diff list | history)
| 1991/0901/sys/src/9/port/devmnt.c:4,122 – 1991/0904/sys/src/9/port/devmnt.c:4,286 (short | long | prev | next) | ||
| 1990/0227 | #include "dat.h" #include "fns.h" #include "errno.h" | |
| 1991/0904 | ||
| 1990/0227 | #include "devtab.h" | |
| 1991/0904 | ||
| 1990/0227 | #include "fcall.h" | |
| 1991/0901 |
| |
| 1991/0904 | #define NTAG 65536 /* 1 <= tag < NTAG */ | |
| 1991/0812 | ||
| 1991/0901 |
| |
| 1991/0904 | typedef struct Mnt Mnt; typedef struct Mnthdr Mnthdr; typedef struct MntQ MntQ; struct Mnt | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1991/0904 | Ref; /* for number of chans, incl. mntpt but not msg */ ulong mntid; /* serial # */ Chan *mntpt; /* channel in user's name space */ MntQ *q; | |
| 1990/0227 | }; | |
| 1991/0901 |
| |
| 1991/0904 | struct MntQ | |
| 1990/0604 | { | |
| 1991/0901 |
| |
| 1991/0904 | 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 */ | |
| 1990/0604 | }; | |
| 1991/0901 |
| |
| 1991/0904 | #define BITROUND 256 #define BUFSIZE (MAXFDATA+MAXMSG) typedef struct Mntbuf Mntbuf; struct Mntbuf | |
| 1990/0227 | { | |
| 1991/0904 | Mntbuf *next; char buf[BUFSIZE+BITROUND]; /* BUG */ }; struct { | |
| 1990/0227 | Lock; | |
| 1991/0901 |
| |
| 1991/0904 | Mntbuf *free; }mntbufalloc; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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 */ }; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | struct { Lock; Mnthdr *arena; Mnthdr *head; Mnthdr *tail; }mnthdralloc; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | struct | |
| 1990/0303 | { | |
| 1991/0901 |
| |
| 1991/0904 | Lock; QLock; MntQ *arena; MntQ *free; }mntqalloc; | |
| 1990/0604 | ||
| 1991/0904 | 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; } | |
| 1990/0227 | void | |
| 1991/0901 |
| |
| 1991/0904 | mbfree(Mntbuf *mb) | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1991/0904 | lock(&mntbufalloc); mb->next = mntbufalloc.free; mntbufalloc.free = mb; unlock(&mntbufalloc); } | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | Mnthdr* mhalloc(Mnt *m) { Mnthdr *mh; int seq; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0227 | } | |
| 1991/0904 | unlock(&mnthdralloc); print("no mnthdrs\n"); if(u == 0) panic("mhalloc"); u->p->state = Wakeme; alarm(1000, wakeme, u->p); sched(); goto loop; } | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0604 | } | |
| 1991/0901 |
| |
| 1991/0904 | panic("no mntqs\n"); /* there MUST be enough */ } | |
| 1990/0604 | ||
| 1991/0901 |
| |
| 1991/0904 | 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); | |
| 1990/0604 | } | |
| 1991/0904 | 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); } | |
| 1990/0227 | void | |
| 1991/0904 | 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; i<conf.nmntbuf; i++,mb++) mb->next = mb+1; --mb; mb->next = 0; mh = ialloc(conf.nmnthdr*sizeof(Mnthdr), 0); mnthdralloc.arena = mh; mnthdralloc.head = mh; for(i=0; i<conf.nmnthdr; i++,mh++){ mh->seq = 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; i<conf.nmntdev; i++,mq++) mq->next = mq+1; --mq; mq->next = 0; } void | |
| 1990/0227 | mntinit(void) { } Chan* | |
| 1991/0901 |
| |
| 1991/0904 | mntattach(char *crud) | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1991/0904 | int i; Mnt *m, *mm; Mnthdr *mh; MntQ *q; Chan *c, *cm; | |
| 1990/0227 | struct bogus{ Chan *chan; char *spec; | |
| 1991/0901/sys/src/9/port/devmnt.c:123,199 – 1991/0904/sys/src/9/port/devmnt.c:287,352 | ||
| 1990/11211 | char *auth; | |
| 1990/0227 | }bogus; | |
| 1991/0901 |
| |
| 1990/0227 |
| |
| 1991/0901 |
| |
| 1990/0227 |
| |
| 1991/0901 |
| |
| 1991/0904 | bogus = *((struct bogus *)crud); | |
| 1991/0901 |
| |
| 1991/0904 | m = mnt; for(i=0; i<conf.nmntdev; i++,m++){ lock(m); if(m->ref == 0) goto Found; unlock(m); | |
| 1991/0901 | } | |
| 1991/0904 | error(Enomntdev); Found: m->ref = 1; | |
| 1990/0227 | unlock(m); | |
| 1991/0904 | 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; | |
| 1990/0604 | ||
| 1991/0901 |
| |
| 1991/0904 | /* * Look for queue to same msg channel */ q = mntqalloc.arena; qlock(&mntqalloc); for(i=0; i<conf.nmntdev; i++,q++) if(q->msg==cm){ lock(q); if(q->ref && q->msg==cm){ m->q = q; q->ref++; unlock(q); goto out; } unlock(q); } m->q = mqalloc(cm); | |
| 1990/0604 | ||
| 1991/0901 |
| |
| 1991/0904 | out: qunlock(&mntqalloc); mh = mhalloc(m); | |
| 1990/0227 | if(waserror()){ | |
| 1991/0901 |
| |
| 1991/0904 | mhfree(mh); | |
| 1990/0227 | close(c); nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0303 | c->mqid = c->qid; | |
| 1991/0904 | mhfree(mh); | |
| 1990/0227 | poperror(); | |
| 1991/0901 |
| |
| 1990/0227 | return c; } | |
| 1991/0901/sys/src/9/port/devmnt.c:201,227 – 1991/0904/sys/src/9/port/devmnt.c:354,381 | ||
| 1990/0227 | mntclone(Chan *c, Chan *nc) { Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; int new; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | new = 0; if(nc == 0){ | |
| 1990/0227 | nc = newchan(); | |
| 1991/0901 |
| |
| 1991/0904 | new = 1; if(waserror()){ close(nc); nexterror(); } | |
| 1990/0227 | } | |
| 1991/0904 | m = mntdev(c, 0); mh = mhalloc(m); | |
| 1990/0227 | if(waserror()){ | |
| 1991/0901 |
| |
| 1991/0904 | mhfree(mh); | |
| 1990/0227 | nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | mh->thdr.type = Tclone; mh->thdr.fid = c->fid; mh->thdr.newfid = nc->fid; mntxmit(m, mh); | |
| 1990/0227 | nc->type = c->type; nc->dev = c->dev; nc->qid = c->qid; | |
| 1991/0901/sys/src/9/port/devmnt.c:231,242 – 1991/0904/sys/src/9/port/devmnt.c:385,398 | ||
| 1990/0227 | nc->mnt = c->mnt; | |
| 1991/0427 | nc->mountid = c->mountid; | |
| 1991/0421 | nc->aux = c->aux; | |
| 1991/0904 | nc->mntindex = c->mntindex; | |
| 1990/0303 | nc->mchan = c->mchan; nc->mqid = c->qid; | |
| 1990/0227 |
| |
| 1991/0901 | ||
| 1991/0904 | mhfree(mh); | |
| 1991/0901 | poperror(); | |
| 1991/0904 | if(new) poperror(); incref(m); | |
| 1990/0227 | return nc; } | |
| 1991/0901/sys/src/9/port/devmnt.c:244,267 – 1991/0904/sys/src/9/port/devmnt.c:400,424 | ||
| 1990/0227 | mntwalk(Chan *c, char *name) { Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; int found; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0227 | } | |
| 1991/0901 |
| |
| 1991/0904 | mntxmit(m, mh); c->qid = mh->rhdr.qid; | |
| 1990/0227 | poperror(); | |
| 1991/0901 |
| |
| 1991/0904 | Out: mhfree(mh); return found; | |
| 1990/0227 | } void | |
| 1991/0901/sys/src/9/port/devmnt.c:268,289 – 1991/0904/sys/src/9/port/devmnt.c:425,448 | ||
| 1990/0227 | mntstat(Chan *c, char *dp) { Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); | |
| 1990/0227 | nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | 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); | |
| 1990/0227 | poperror(); | |
| 1991/0901 |
| |
| 1990/0227 | } Chan* | |
| 1991/0901/sys/src/9/port/devmnt.c:290,314 – 1991/0904/sys/src/9/port/devmnt.c:449,472 | ||
| 1990/0227 | mntopen(Chan *c, int omode) { Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); | |
| 1990/0227 | nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | mh->thdr.type = Topen; mh->thdr.fid = c->fid; mh->thdr.mode = omode; mntxmit(m, mh); c->qid = mh->rhdr.qid; mhfree(mh); poperror(); | |
| 1990/0227 | c->offset = 0; c->mode = openmode(omode); c->flag |= COPEN; | |
| 1991/0901 |
| |
| 1990/0227 | return c; } | |
| 1991/0901/sys/src/9/port/devmnt.c:316,341 – 1991/0904/sys/src/9/port/devmnt.c:474,499 | ||
| 1990/0227 | mntcreate(Chan *c, char *name, int omode, ulong perm) { Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); | |
| 1990/0227 | nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | 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(); | |
| 1990/0227 | c->flag |= COPEN; c->mode = openmode(omode); | |
| 1991/0901 |
| |
| 1991/0904 | c->qid = mh->rhdr.qid; | |
| 1990/0227 | } void | |
| 1991/0901/sys/src/9/port/devmnt.c:342,373 – 1991/0904/sys/src/9/port/devmnt.c:500,533 | ||
| 1990/0604 | mntclunk(Chan *c, int t) | |
| 1990/0227 | { Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; MntQ *q; int waserr; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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(); | |
| 1990/0227 | } | |
| 1990/0604 | void | |
| 1991/0901/sys/src/9/port/devmnt.c:376,417 – 1991/0904/sys/src/9/port/devmnt.c:536,596 | ||
| 1990/0604 | mntclunk(c, Tclunk); } | |
| 1991/0901 |
| |
| 1991/0904 | long mntreadwrite(Chan *c, void *vbuf, long n, int type, ulong offset) | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1990/0227 | Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; long nt, nr, count; char *buf; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | buf = vbuf; count = 0; m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); | |
| 1990/0227 | nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | 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); | |
| 1990/0227 | poperror(); | |
| 1991/0901 |
| |
| 1991/0904 | return count; | |
| 1990/0227 | } long | |
| 1991/0411 | mntread(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1991/0904 | long i; uchar *b; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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; } } | |
| 1990/0227 | return n; } | |
| 1991/0901/sys/src/9/port/devmnt.c:418,732 – 1991/0904/sys/src/9/port/devmnt.c:597,968 | ||
| 1990/0227 | long | |
| 1991/0411 | mntwrite(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1991/0904 | return mntreadwrite(c, buf, n, Twrite, offset); | |
| 1990/0227 | } | |
| 1991/0901 |
| |
| 1991/0904 | void mntremove(Chan *c) | |
| 1990/0227 | { | |
| 1991/0904 | mntclunk(c, Tremove); } void mntwstat(Chan *c, char *dp) { | |
| 1990/0227 | Mnt *m; | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | m = mntdev(c, 0); mh = mhalloc(m); if(waserror()){ mhfree(mh); | |
| 1990/0227 | nexterror(); } | |
| 1991/0901 |
| |
| 1991/0904 | mh->thdr.type = Twstat; mh->thdr.fid = c->fid; memmove(mh->thdr.stat, dp, DIRLEN); mntxmit(m, mh); mhfree(mh); | |
| 1990/0227 | poperror(); | |
| 1991/0901 |
| |
| 1990/0227 | } void | |
| 1991/0901 |
| |
| 1991/0904 | mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */ | |
| 1990/0604 | { | |
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/1123 | } } | |
| 1991/0904 | /* * m->q is unlocked. Send Tflush message to flush omh->tag. * Cut off all errors. Caller will free omh */ | |
| 1990/1123 | void | |
| 1991/0901 |
| |
| 1991/0904 | mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */ | |
| 1990/1123 | { | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *mh; | |
| 1990/1124 | ||
| 1991/0901 |
| |
| 1991/0904 | if(omh->thdr.type == Tflush){ omh->flushing = 0; | |
| 1990/1124 | return; | |
| 1991/0808 | } | |
| 1990/1124 | ||
| 1991/0901 |
| |
| 1991/0904 | mh = mhalloc(m); if(waserror()){ omh->flushing = 0; mhfree(mh); return; /* no more errors please */ | |
| 1990/1124 | } | |
| 1991/0901 |
| |
| 1991/0904 | mh->thdr.type = Tflush; mh->thdr.oldtag = omh->thdr.tag; mntxmit(m, mh); omh->flushing = 0; mhfree(mh); poperror(); | |
| 1990/1124 | } void | |
| 1991/0901 |
| |
| 1991/0904 | mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */ | |
| 1990/1124 | { | |
| 1991/0901 |
| |
| 1991/0904 | Mnthdr *w; MntQ *q; | |
| 1990/0604 | ||
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0604 | } | |
| 1991/0901 |
| |
| 1991/0904 | }else mntwunlink(q, mh); qunlock(q); mntflush(m, mh); | |
| 1990/0604 | } | |
| 1990/11211 | ||
| 1991/0901 |
| |
| 1991/0904 | int mntreadreply(void *a) | |
| 1990/0717 | { | |
| 1991/0901 |
| |
| 1991/0904 | return ((Mnthdr *)a)->readreply; | |
| 1990/0717 | } | |
| 1990/11211 | ||
| 1990/0604 | void | |
| 1991/0901 |
| |
| 1991/0904 | mntxmit(Mnt *m, Mnthdr *mh) | |
| 1990/0227 | { | |
| 1991/0901 |
| |
| 1991/0904 | ulong n; Mntbuf *mbw; Mnthdr *w, *ow, *h; MntQ *q; int qlocked, tag, written; | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1991/0808 | } | |
| 1991/0901 |
| |
| 1991/0904 | mbfree(mbw); nexterror(); | |
| 1990/0227 | } | |
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0604 | ||
| 1991/0901 |
| |
| 1991/0904 | incref(q); if(waserror()){ /* 2 */ mqfree(q); nexterror(); | |
| 1990/0227 | } | |
| 1991/0904 | if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){ print("short write in mntxmit\n"); error(Eshortmsg); } | |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | /* * 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 */ | |
| 1990/0511 | ||
| 1991/0901 |
| |
| 1990/0511 | ||
| 1991/0901 |
| |
| 1991/0904 | if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){ print("format error in mntxmit\n"); error(Ebadmsg); | |
| 1990/11211 | } | |
| 1991/0901 |
| |
| 1990/0511 | ||
| 1991/0901 |
| |
| 1990/0511 | ||
| 1991/0901 |
| |
| 1991/0904 | /* * Various checks */ if(mh->rhdr.tag != mh->thdr.tag){ print("tag mismatch %d %d\n", mh->rhdr.tag, mh->thdr.tag); error(Ebadmsg); | |
| 1990/03081 | } | |
| 1991/0901 |
| |
| 1991/0904 | 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); } | |
| 1991/0901 |
| |
| 1991/0904 | /* * 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; | |
| 1991/0901 |
| |
| 1991/0904 | 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(); | |
| 1990/0703 | } | |
| 1991/0901 |
| |
| 1991/0904 | 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; | |
| 1990/0227 | } | |
| 1991/0901 |
| |
| 1990/0227 | ||
| 1991/0901 |
| |
| 1991/0904 | Respond: mqfree(q); poperror(); /* 2 */ if(mh->rhdr.type == Rerror){ if(m->mntpt) errors(mh->rhdr.ename); | |
| 1990/11211 | error(Eshutdown); | |
| 1991/0901 |
| |
| 1991/0904 | } /* * 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 */ | |
| 1990/0717 | } | |
| 1990/1220 | void | |
| 1991/0901 |
| |
| 1990/0717 |
| |
| 1991/0901 |
| |
| 1990/0717 | ||
| 1991/0901 |
| |
| 1990/0227 |
| |
| 1991/0901 |
| |
| 1991/0904 | int i; MntQ *q; Mnthdr *h; Proc *p; | |
| 1991/0901 | ||
| 1991/0904 | for(i=0; i<conf.nmntdev; i++){ q = &mntqalloc.arena[i]; if(!q->msg) 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"); } } | |