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