M pc/bbmalloc.c => pc/bbmalloc.c +29 -55
@@ 3,77 3,51 @@
#include "mem.h"
#include "dat.h"
#include "fns.h"
-#include "io.h"
-/*
- * Allocate memory for use in kernel bitblts.
- * The allocated memory must have a flushed instruction
- * cache, and the data cache must be flushed by bbdflush().
- * To avoid the need for frequent cache flushes, the memory
- * is allocated out of an arena, and the i-cache is only
- * flushed when it has to be reused. By returning an
- * address in non-cached space, the need for flushing the
- * d-cache is avoided.
- *
- * On the safari, all this is unnecessary, since the
- * only icache is a miniscule prefetch buffer.
- *
- * Currently, the only kernel users of bitblt are devbit,
- * print, and the cursor stuff in devbit. The cursor
- * can get drawn at clock interrupt time, so it might need
- * to bbmalloc while another bitblt is going on.
- *
- * This code will have to be interlocked if we ever get
- * a multiprocessor with a bitmapped display.
- */
+static char bbarena[10000];
+static char bbused[10];
-/* a 0->3 bitblt can take 900 words */
-enum {
- nbbarena=8192 /* number of words in an arena */
-};
-
-static ulong bbarena[nbbarena];
-static ulong *bbcur = bbarena;
-static ulong *bblast = 0;
-
-void *
-bbmalloc(int nbytes)
+void*
+bbmalloc(int n)
{
- int nw;
- int s;
- ulong *ans;
+ char *a;
+ int s, i;
- nw = nbytes/sizeof(long);
s = splhi();
- if(bbcur + nw > &bbarena[nbbarena])
- ans = bbarena;
- else
- ans = bbcur;
- bbcur = ans + nw;
+ a = memchr(bbused, 0, sizeof(bbused));
+ if(a) {
+ i = a - bbused;
+ a = bbarena + i*n;
+ if(a+n <= bbarena+sizeof(bbarena)) {
+ bbused[i] = 1;
+ splx(s);
+ return a;
+ }
+ }
splx(s);
-/*
- if(ans == bbarena)
- icflush(ans, sizeof(bbarena));
-*/
- bblast = ans;
- ans = (void *)ans;
- return ans;
+ print("too many bbmallocs\n");
+ return bbarena;
}
void
-bbfree(void *p, int n)
+bbfree(void *va, int n)
{
- ulong *up;
- int s;
+ int s, i;
s = splhi();
- if(p == bblast)
- bbcur = (ulong *)(((char *)bblast) + n);
+ i = ((char*)va - bbarena) /n;
+ if(i >= 0 && i < sizeof(bbused) && bbused[i]){
+ bbused[i] = 0;
+ splx(s);
+ return;
+ }
splx(s);
+ print("sanity bbfree\n");
}
-void *
+void*
bbdflush(void *p, int n)
{
return p;
}
+
M pc/devuart.c => pc/devuart.c +4 -1
@@ 259,7 259,7 @@ uartintr(Uart *up)
break;
case 0: /* modem status */
- l = uartrdreg(up, Mstat);
+ uartrdreg(up, Mstat);
break;
default:
@@ 529,6 529,9 @@ uartkproc(void *a)
int n;
ulong frame, overrun;
+ frame = 0;
+ overrun = 0;
+
if(waserror())
print("uartkproc got an error\n");
M pc/io.h => pc/io.h +1 -1
@@ 4,7 4,7 @@
enum
{
Faultvec= 14, /* page fault */
- Int0vec= 16, /* first 8259 */
+ Int0vec= 24, /* first 8259 */
Clockvec= Int0vec+0, /* clock interrupts */
Kbdvec= Int0vec+1, /* keyboard interrupts */
Uart1vec= Int0vec+3, /* modem line */
M pc/kbd.c => pc/kbd.c +13 -10
@@ 277,16 277,19 @@ mousecmd(int cmd)
unsigned int c;
int tries;
- for(tries=0; tries < 10; tries++){
- if(outready() < 0)
- return -1;
- outb(Cmd, 0xD4);
- if(outready() < 0)
- return -1;
- outb(Data, cmd);
- if(inready() < 0)
- return -1;
- c = inb(Data);
+ c = 0;
+ do{
+ for(tries=0; tries < 10; tries++){
+ if(outready() < 0)
+ return -1;
+ outb(Cmd, 0xD4);
+ if(outready() < 0)
+ return -1;
+ outb(Data, cmd);
+ if(inready() < 0)
+ return -1;
+ c = inb(Data);
+ }
} while(c == 0xFE);
if(c != 0xFA)
return -1;
M pc/l.s => pc/l.s +32 -28
@@ 343,34 343,6 @@ TEXT intr16(SB),$0
PUSHL $0
PUSHL $16
JMP intrcommon
-TEXT intr17(SB),$0
- PUSHL $0
- PUSHL $17
- JMP intrcommon
-TEXT intr18(SB),$0
- PUSHL $0
- PUSHL $18
- JMP intrcommon
-TEXT intr19(SB),$0
- PUSHL $0
- PUSHL $19
- JMP intrcommon
-TEXT intr20(SB),$0
- PUSHL $0
- PUSHL $20
- JMP intrcommon
-TEXT intr21(SB),$0
- PUSHL $0
- PUSHL $21
- JMP intrcommon
-TEXT intr22(SB),$0
- PUSHL $0
- PUSHL $22
- JMP intrcommon
-TEXT intr23(SB),$0
- PUSHL $0
- PUSHL $23
- JMP intrcommon
TEXT intr24(SB),$0
PUSHL $0
PUSHL $24
@@ 403,6 375,38 @@ TEXT intr31(SB),$0
PUSHL $0
PUSHL $31
JMP intrcommon
+TEXT intr32(SB),$0
+ PUSHL $0
+ PUSHL $16
+ JMP intrcommon
+TEXT intr33(SB),$0
+ PUSHL $0
+ PUSHL $33
+ JMP intrcommon
+TEXT intr34(SB),$0
+ PUSHL $0
+ PUSHL $34
+ JMP intrcommon
+TEXT intr35(SB),$0
+ PUSHL $0
+ PUSHL $35
+ JMP intrcommon
+TEXT intr36(SB),$0
+ PUSHL $0
+ PUSHL $36
+ JMP intrcommon
+TEXT intr37(SB),$0
+ PUSHL $0
+ PUSHL $37
+ JMP intrcommon
+TEXT intr38(SB),$0
+ PUSHL $0
+ PUSHL $38
+ JMP intrcommon
+TEXT intr39(SB),$0
+ PUSHL $0
+ PUSHL $39
+ JMP intrcommon
TEXT intr64(SB),$0
PUSHL $0
PUSHL $64
M pc/trap.c => pc/trap.c +15 -13
@@ 14,10 14,11 @@ void intr0(void), intr1(void), intr2(void), intr3(void);
void intr4(void), intr5(void), intr6(void), intr7(void);
void intr8(void), intr9(void), intr10(void), intr11(void);
void intr12(void), intr13(void), intr14(void), intr15(void);
-void intr16(void), intr17(void), intr18(void), intr19(void);
-void intr20(void), intr21(void), intr22(void), intr23(void);
+void intr16(void);
void intr24(void), intr25(void), intr26(void), intr27(void);
void intr28(void), intr29(void), intr30(void), intr31(void);
+void intr32(void), intr33(void), intr34(void), intr35(void);
+void intr36(void), intr37(void), intr38(void), intr39(void);
void intr64(void);
void intrbad(void);
@@ 78,11 79,11 @@ trapinit(void)
/*
* set all interrupts to panics
*/
- for(i = 32; i < 256; i++)
+ for(i = 0; i < 256; i++)
sethvec(i, intrbad, SEGTG, 0);
/*
- * set the standard traps
+ * 80386 processor (and coprocessor) traps
*/
sethvec(0, intr0, SEGTG, 0);
sethvec(1, intr1, SEGTG, 0);
@@ 100,18 101,11 @@ trapinit(void)
sethvec(13, intr13, SEGTG, 0);
sethvec(14, intr14, SEGTG, 0);
sethvec(15, intr15, SEGTG, 0);
+ sethvec(16, intr16, SEGTG, 0);
/*
- * set the standard devices
+ * device interrupts
*/
- sethvec(16, intr16, SEGIG, 0);
- sethvec(17, intr17, SEGIG, 0);
- sethvec(18, intr18, SEGIG, 0);
- sethvec(19, intr19, SEGIG, 0);
- sethvec(20, intr20, SEGIG, 0);
- sethvec(21, intr21, SEGIG, 0);
- sethvec(22, intr22, SEGIG, 0);
- sethvec(23, intr23, SEGIG, 0);
sethvec(24, intr24, SEGIG, 0);
sethvec(25, intr25, SEGIG, 0);
sethvec(26, intr26, SEGIG, 0);
@@ 120,6 114,14 @@ trapinit(void)
sethvec(29, intr29, SEGIG, 0);
sethvec(30, intr30, SEGIG, 0);
sethvec(31, intr31, SEGIG, 0);
+ sethvec(32, intr32, SEGIG, 0);
+ sethvec(33, intr33, SEGIG, 0);
+ sethvec(34, intr34, SEGIG, 0);
+ sethvec(35, intr35, SEGIG, 0);
+ sethvec(36, intr36, SEGIG, 0);
+ sethvec(37, intr37, SEGIG, 0);
+ sethvec(38, intr38, SEGIG, 0);
+ sethvec(39, intr39, SEGIG, 0);
/*
* system calls
M pc/vga.c => pc/vga.c +1 -4
@@ 148,13 148,10 @@ munch(void)
void
screeninit(void)
{
- uchar *display;
int i, j, k;
int c;
ulong *l;
- display = (uchar *)SCREENMEM;
-
arout(Acpe, 0x0f); /* enable all planes */
arout(Amode, 0x01); /* graphics mode - 4 bit pixels */
grout(Gmisc, 0x01); /* graphics mode */
@@ 268,7 265,7 @@ hwcursmove(int x, int y)
}
void
-mouseclock(void) /* called splhi */
+mouseclock(void)
{
mouseupdate(1);
}
M port/devmnt.c => port/devmnt.c +775 -539
@@ 4,108 4,268 @@
#include "dat.h"
#include "fns.h"
#include "errno.h"
+
#include "devtab.h"
+
#include "fcall.h"
-typedef struct Mntrpc Mntrpc;
-typedef struct Mnt Mnt;
-
-struct Mntrpc
-{
- 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 */
-};
+#define NTAG 65536 /* 1 <= tag < NTAG */
+
+typedef struct Mnt Mnt;
+typedef struct Mnthdr Mnthdr;
+typedef struct MntQ MntQ;
struct Mnt
{
- 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 */
+ Ref; /* for number of chans, incl. mntpt but not msg */
+ ulong mntid; /* serial # */
+ Chan *mntpt; /* channel in user's name space */
+ MntQ *q;
+};
+
+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 */
+};
+
+#define BITROUND 256
+#define BUFSIZE (MAXFDATA+MAXMSG)
+typedef struct Mntbuf Mntbuf;
+struct Mntbuf
+{
+ Mntbuf *next;
+ char buf[BUFSIZE+BITROUND]; /* BUG */
};
-struct Mntalloc
+struct
{
Lock;
- Mnt *mntfree;
- Mnt *mntarena;
- Mntrpc *rpcfree;
- int id;
-}mntalloc;
-
-#define BITBOTCH 256
-#define MAXRPC (MAXFDATA+MAXMSG+BITBOTCH)
-#define limit(n, max) (n > max ? max : n)
-
-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*);
-
-enum
-{
- Tagspace = 1,
- Flushspace = 64,
- Flushtag = 512,
+ Mntbuf *free;
+}mntbufalloc;
+
+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 */
};
+struct
+{
+ Lock;
+ Mnthdr *arena;
+ Mnthdr *head;
+ Mnthdr *tail;
+}mnthdralloc;
+
+struct
+{
+ Lock;
+ QLock;
+ MntQ *arena;
+ MntQ *free;
+}mntqalloc;
+
+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(Mnt *m)
+{
+ Mnthdr *mh;
+ int seq;
+
+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;
+ }
+ unlock(&mnthdralloc);
+ print("no mnthdrs\n");
+ if(u == 0)
+ panic("mhalloc");
+ u->p->state = Wakeme;
+ alarm(1000, wakeme, u->p);
+ sched();
+ goto loop;
+}
+
+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;
+ }
+ 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);
+}
+
+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);
+}
+
void
mntreset(void)
{
- Mnt *me, *md;
- Mntrpc *re, *rd;
- ushort tag, ftag;
-
- 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;
-
- if(conf.nmntbuf > Flushtag) {
- print("devmnt: buffers limited to %d\n", Flushtag);
- conf.nmntbuf = Flushtag;
- }
-
- 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);
- }
- re[-1].list = 0;
-
- mntalloc.id = 1;
+ 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
@@ 114,86 274,79 @@ mntinit(void)
}
Chan*
-mntattach(char *muxattach)
+mntattach(char *crud)
{
- Mnt *m, *e;
+ int i;
+ Mnt *m, *mm;
+ Mnthdr *mh;
+ MntQ *q;
+ Chan *c, *cm;
struct bogus{
Chan *chan;
char *spec;
char *auth;
}bogus;
- 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);
- }
- }
- lock(&mntalloc);
- if(mntalloc.mntfree == 0) {
- unlock(&mntalloc);
- error(Enomntdev);
+ bogus = *((struct bogus *)crud);
+
+ m = mnt;
+ for(i=0; i<conf.nmntdev; i++,m++){
+ lock(m);
+ if(m->ref == 0)
+ goto Found;
+ unlock(m);
}
- m = mntalloc.mntfree;
- mntalloc.mntfree = m->list;
- m->id = mntalloc.id++;
- lock(m);
- unlock(&mntalloc);
+ error(Enomntdev);
+
+ Found:
m->ref = 1;
- 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);
unlock(m);
+ 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;
+
+ /*
+ * 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);
- return mattach(m, bogus.spec, bogus.auth);
-}
-
-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;
-
+ out:
+ qunlock(&mntqalloc);
+ mh = mhalloc(m);
if(waserror()){
- mntfree(r);
+ mhfree(mh);
close(c);
nexterror();
}
- 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;
+ 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;
c->mqid = c->qid;
+ mhfree(mh);
poperror();
- mntfree(r);
return c;
}
@@ 201,27 354,28 @@ Chan*
mntclone(Chan *c, Chan *nc)
{
Mnt *m;
- Mntrpc *r;
- int alloc = 0;
+ Mnthdr *mh;
+ int new;
- m = mntchk(c);
- r = mntralloc();
- if(nc == 0) {
+ new = 0;
+ if(nc == 0){
nc = newchan();
- alloc = 1;
+ new = 1;
+ if(waserror()){
+ close(nc);
+ nexterror();
+ }
}
+ m = mntdev(c, 0);
+ mh = mhalloc(m);
if(waserror()){
- mntfree(r);
- if(alloc)
- close(nc);
+ mhfree(mh);
nexterror();
}
-
- r->request.type = Tclone;
- r->request.fid = c->fid;
- r->request.newfid = nc->fid;
- mountrpc(m, r);
-
+ 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;
@@ 231,12 385,14 @@ mntclone(Chan *c, Chan *nc)
nc->mnt = c->mnt;
nc->mountid = c->mountid;
nc->aux = c->aux;
+ nc->mntindex = c->mntindex;
nc->mchan = c->mchan;
nc->mqid = c->qid;
- incref(m);
-
+ mhfree(mh);
poperror();
- mntfree(r);
+ if(new)
+ poperror();
+ incref(m);
return nc;
}
@@ 244,71 400,73 @@ int
mntwalk(Chan *c, char *name)
{
Mnt *m;
- Mntrpc *r;
-
- m = mntchk(c);
- r = mntralloc();
- if(waserror()) {
- mntfree(r);
- return 0;
+ Mnthdr *mh;
+ int found;
+
+ 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;
}
- r->request.type = Twalk;
- r->request.fid = c->fid;
- strncpy(r->request.name, name, NAMELEN);
- mountrpc(m, r);
-
- c->qid = r->reply.qid;
-
+ mntxmit(m, mh);
+ c->qid = mh->rhdr.qid;
poperror();
- mntfree(r);
- return 1;
+ Out:
+ mhfree(mh);
+ return found;
}
void
mntstat(Chan *c, char *dp)
{
Mnt *m;
- Mntrpc *r;
+ Mnthdr *mh;
- m = mntchk(c);
- r = mntralloc();
- if(waserror()) {
- mntfree(r);
+ m = mntdev(c, 0);
+ mh = mhalloc(m);
+ if(waserror()){
+ mhfree(mh);
nexterror();
}
- r->request.type = Tstat;
- r->request.fid = c->fid;
- mountrpc(m, r);
-
- memmove(dp, r->reply.stat, DIRLEN);
- mntdirfix((uchar*)dp, c);
+ 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);
poperror();
- mntfree(r);
}
Chan*
mntopen(Chan *c, int omode)
{
Mnt *m;
- Mntrpc *r;
+ Mnthdr *mh;
- m = mntchk(c);
- r = mntralloc();
- if(waserror()) {
- mntfree(r);
+ m = mntdev(c, 0);
+ mh = mhalloc(m);
+ if(waserror()){
+ mhfree(mh);
nexterror();
}
- r->request.type = Topen;
- r->request.fid = c->fid;
- r->request.mode = omode;
- mountrpc(m, r);
-
- c->qid = r->reply.qid;
+ 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;
- poperror();
- mntfree(r);
return c;
}
@@ 316,58 474,60 @@ void
mntcreate(Chan *c, char *name, int omode, ulong perm)
{
Mnt *m;
- Mntrpc *r;
+ Mnthdr *mh;
- m = mntchk(c);
- r = mntralloc();
- if(waserror()) {
- mntfree(r);
+ m = mntdev(c, 0);
+ mh = mhalloc(m);
+ if(waserror()){
+ mhfree(mh);
nexterror();
}
- 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;
+ 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);
- poperror();
- mntfree(r);
+ c->qid = mh->rhdr.qid;
}
void
mntclunk(Chan *c, int t)
{
Mnt *m;
- 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;
- }
-
- r->request.type = t;
- r->request.fid = c->fid;
- mountrpc(m, r);
- nexterror();
+ Mnthdr *mh;
+ MntQ *q;
+ int waserr;
+
+ 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();
}
void
@@ 376,357 536,433 @@ mntclose(Chan *c)
mntclunk(c, Tclunk);
}
-void
-mntremove(Chan *c)
-{
- mntclunk(c, Tremove);
-}
-
-void
-mntwstat(Chan *c, char *dp)
+long
+mntreadwrite(Chan *c, void *vbuf, long n, int type, ulong offset)
{
Mnt *m;
- Mntrpc *r;
-
- m = mntchk(c);
- r = mntralloc();
- if(waserror()) {
- mntfree(r);
+ Mnthdr *mh;
+ long nt, nr, count;
+ char *buf;
+
+ buf = vbuf;
+ count = 0;
+ m = mntdev(c, 0);
+ mh = mhalloc(m);
+ if(waserror()){
+ mhfree(mh);
nexterror();
}
- r->request.type = Twstat;
- r->request.fid = c->fid;
- memmove(r->request.stat, dp, DIRLEN);
- mountrpc(m, r);
+ 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();
- mntfree(r);
+ return count;
}
long
mntread(Chan *c, void *buf, long n, ulong offset)
{
- uchar *p, *e;
-
- 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);
-
+ long i;
+ uchar *b;
+
+ 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;
+ }
+ }
return n;
}
long
mntwrite(Chan *c, void *buf, long n, ulong offset)
{
- return mntrdwr(Twrite, c, buf, n, offset);
+ return mntreadwrite(c, buf, n, Twrite, offset);
}
-long
-mntrdwr(int type, Chan *c, void *buf, long n, ulong offset)
+void
+mntremove(Chan *c)
+{
+ mntclunk(c, Tremove);
+}
+
+void
+mntwstat(Chan *c, char *dp)
{
Mnt *m;
- Mntrpc *r;
- ulong cnt, nr;
- char *uba;
-
- r = mntralloc();
- m = mntchk(c);
- if(waserror()) {
- mntfree(r);
+ Mnthdr *mh;
+
+ m = mntdev(c, 0);
+ mh = mhalloc(m);
+ if(waserror()){
+ mhfree(mh);
nexterror();
}
- 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;
- }
+ mh->thdr.type = Twstat;
+ mh->thdr.fid = c->fid;
+ memmove(mh->thdr.stat, dp, DIRLEN);
+ mntxmit(m, mh);
+ mhfree(mh);
poperror();
- mntfree(r);
- return cnt;
}
void
-mountrpc(Mnt *m, Mntrpc *r)
-{
- 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");
+mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */
+{
+ 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;
}
}
+/*
+ * m->q is unlocked. Send Tflush message to flush omh->tag.
+ * Cut off all errors. Caller will free omh
+ */
void
-mountio(Mnt *m, Mntrpc *r)
+mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */
{
- int n;
+ Mnthdr *mh;
- 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);
+ if(omh->thdr.type == Tflush){
+ omh->flushing = 0;
return;
}
- /* 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;
- }
- m->rip = u->p;
- unlock(m);
-
- while(r->done == 0) {
- mntrpcread(m, r);
- mountmux(m, r);
+ mh = mhalloc(m);
+ if(waserror()){
+ omh->flushing = 0;
+ mhfree(mh);
+ return; /* no more errors please */
}
- mntgate(m);
+ mh->thdr.type = Tflush;
+ mh->thdr.oldtag = omh->thdr.tag;
+ mntxmit(m, mh);
+ omh->flushing = 0;
+ mhfree(mh);
+ poperror();
}
void
-mntrpcread(Mnt *m, Mntrpc *r)
-{
- int n;
-
- for(;;) {
- if(waserror()) {
- if(mntflush(m, r) == 0) {
- if(m->mux == 0)
- mntgate(m);
- nexterror();
- }
- continue;
+mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */
+{
+ Mnthdr *w;
+ MntQ *q;
+
+ 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;
}
- 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;
- }
+ }else
+ mntwunlink(q, mh);
+ qunlock(q);
+ mntflush(m, mh);
}
-void
-mntgate(Mnt *m)
+int
+mntreadreply(void *a)
{
- 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);
+ return ((Mnthdr *)a)->readreply;
}
void
-mountmux(Mnt *m, Mntrpc *r)
-{
- Mntrpc **l, *q;
- int done;
- char *dp;
-
- 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;
+mntxmit(Mnt *m, Mnthdr *mh)
+{
+ ulong n;
+ Mntbuf *mbw;
+ Mnthdr *w, *ow, *h;
+ MntQ *q;
+ int qlocked, tag, written;
+
+ 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;
}
- 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;
+ mbfree(mbw);
+ nexterror();
}
- unlock(m);
- return;
-
-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);
+ 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;
+
+ incref(q);
+ if(waserror()){ /* 2 */
+ mqfree(q);
+ nexterror();
}
-
-}
-
-int
-mntflush(Mnt *m, Mntrpc *r)
-{
- Fcall flush;
- int n;
-
- 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;
+ if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n, 0) != n){
+ print("short write in mntxmit\n");
+ error(Eshortmsg);
}
- (*devtab[m->c->type].write)(m->c, r->flush, n, 0);
- poperror();
- lock(m);
- if(!r->done)
- r->flushed = 1;
- unlock(m);
- return 1;
-}
-
-Mntrpc *
-mntralloc(void)
-{
- Mntrpc *new;
- 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");
+ /*
+ * 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 */
+
+ if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
+ print("format error in mntxmit\n");
+ error(Ebadmsg);
}
-}
-
-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);
-}
+ /*
+ * Various checks
+ */
+ 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);
+ }
+ 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);
+ }
-void
-mntqrm(Mnt *m, Mntrpc *r)
-{
- Mntrpc **l, *f;
+ /*
+ * 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;
- 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;
+ 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();
+ }
+ 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;
}
- l = &f->list;
+ 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;
}
- unlock(m);
-}
-
-Mnt *
-mntchk(Chan *c)
-{
- Mnt *m;
- m = &mntalloc.mntarena[c->mntindex];
- if(m->id != c->dev)
+ Respond:
+ mqfree(q);
+ poperror(); /* 2 */
+ if(mh->rhdr.type == Rerror){
+ if(m->mntpt)
+ errors(mh->rhdr.ename);
error(Eshutdown);
- return m;
-}
-
-void
-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;
+ }
+ /*
+ * 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 */
}
void
mntdump(void)
{
-}
+ int i;
+ MntQ *q;
+ Mnthdr *h;
+ Proc *p;
+ 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");
+ }
+}
M port/devnonet.c => port/devnonet.c +2 -1
@@ 948,7 948,8 @@ norack(Noconv *cp, int mid)
cp->rexmit = 0;
cp->lastacked = mid;
mp->acked = 1;
- freeb(mp->first);
+ if(mp->first)
+ freeb(mp->first);
mp->first = 0;
/*
M port/stream.c => port/stream.c +1 -0
@@ 1095,6 1095,7 @@ streamread(Chan *c, void *vbuf, long n)
left = n;
qlock(&s->rdlock);
tofree = 0;
+ q = 0;
if(waserror()){
/*
* put any partially read message back into the
M port/sysfile.c => port/sysfile.c +2 -4
@@ 34,7 34,7 @@ fdtochan(int fd, int mode)
{
Chan *c;
- USED(c);
+ c = 0;
if(fd<0 || NFD<=fd || (c = u->p->fgrp->fd[fd])==0)
error(Ebadfd);
if(mode<0 || c->mode==ORDWR)
@@ 183,9 183,7 @@ fdclose(int fd, int flag)
long
sysclose(ulong *arg)
{
- Chan *c;
-
- c = fdtochan(arg[0], -1);
+ fdtochan(arg[0], -1);
fdclose(arg[0], 0);
return 0;