## 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; i<conf.nmntdev; i++,m++) /* use a hash table some day */
if(m->mntid == 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; i<conf.nmntbuf-1; i++)
mb[i].next = &mb[i+1];
mb[i].next = 0;
mntbufalloc.free = mb;
mh = ialloc(conf.nmnthdr*sizeof(Mnthdr), 0);
for(i=0; i<conf.nmnthdr-1; i++)
mh[i].next = &mh[i+1];
mh[i].next = 0;
mnthdralloc.free = mh;
}
void
mntinit(void)
{
}
Chan*
mntattach(char *spec)
{
int i;
Mnt *m;
Mnthdr *mh;
Chan *c, *cm;
struct bogus{
Chan *chan;
char *spec;
}bogus;
bogus = *((struct bogus *)spec);
spec = bogus.spec;
m = mnt;
for(i=0; i<conf.nmntdev; i++,m++){
lock(m);
if(m->ref == 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; 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();
m->q->msg = cm;
.
191a
.
174a
MntQ *q;
.
173c
Mnt *m, *mm;
.
161a
mq = ialloc(conf.nmntdev*sizeof(MntQ), 0);
for(i=0; i<conf.nmntdev-1; i++)
mq[i].next = &mq[i+1];
mq[i].next = 0;
mntqalloc.arena = mq;
mntqalloc.free = mq;
.
147a
MntQ *mq;
.
133c
if(m->q == 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; 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)", 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; i<conf.nmnthdr-1; i++){
.
197c
error(Eshutdown);
.
12d
## diffname gnot/devmnt.c 1990/1123
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/devmnt.c /n/bootesdump/1990/1123/sys/src/9/68020/devmnt.c
781a
mh->prev = 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
|