| plan 9 kernel history: overview | file list | diff list |
1991/0911/port/devmnt.c (diff list | history)
| 1991/0910/sys/src/9/port/devmnt.c:4,259 – 1991/0911/sys/src/9/port/devmnt.c:4,124 (short | long | prev | next) | ||
| 1990/0227 | #include "dat.h" #include "fns.h" #include "errno.h" | |
| 1991/0904 | ||
| 1990/0227 | #include "devtab.h" | |
| 1991/0904 | ||
| 1990/0227 | #include "fcall.h" | |
| 1991/0904 |
| |
| 1991/0911 | typedef struct Mntrpc Mntrpc; typedef struct Mnt Mnt; | |
| 1991/0904 |
| |
| 1991/0911 | struct Mntrpc | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1991/0911 | 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 */ | |
| 1990/0227 | }; | |
| 1991/0904 |
| |
| 1991/0911 | struct Mnt | |
| 1990/0604 | { | |
| 1991/0904 |
| |
| 1991/0911 | 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 */ | |
| 1990/0604 | }; | |
| 1991/0904 |
| |
| 1991/0911 | struct Mntalloc | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1990/0227 | Lock; | |
| 1991/0904 |
| |
| 1991/0911 | Mnt *mntfree; Mnt *mntarena; Mntrpc *rpcfree; Mntrpc *rpcarena; int id; }mntalloc; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | #define BITBOTCH 256 #define MAXRPC (MAXFDATA+MAXMSG+BITBOTCH) #define limit(n, max) (n > max ? max : n) | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | 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*); | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0911 | enum | |
| 1990/0303 | { | |
| 1991/0904 |
| |
| 1991/0911 | Tagspace = 1, Flushspace = 64, Flushtag = 512, }; | |
| 1990/0604 | ||
| 1991/0904 |
| |
| 1990/0227 | void | |
| 1991/0904 |
| |
| 1991/0911 | mntreset(void) | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1991/0911 | Mnt *me, *md; Mntrpc *re, *rd; ushort tag, ftag; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | 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; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | if(conf.nmntbuf > Flushtag) { print("devmnt: buffers limited to %d\n", Flushtag); conf.nmntbuf = Flushtag; | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | 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); | |
| 1990/0604 | } | |
| 1991/0904 |
| |
| 1991/0911 | re[-1].list = 0; | |
| 1990/0604 | ||
| 1991/0904 |
| |
| 1991/0911 | mntalloc.id = 1; | |
| 1990/0604 | } | |
| 1991/0904 |
| |
| 1990/0227 | void | |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1990/0227 | mntinit(void) { } Chan* | |
| 1991/0904 |
| |
| 1991/0911 | mntattach(char *muxattach) | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1991/0911 | Mnt *m, *e; | |
| 1990/0227 | struct bogus{ Chan *chan; char *spec; | |
| 1991/0910/sys/src/9/port/devmnt.c:260,325 – 1991/0911/sys/src/9/port/devmnt.c:125,201 | ||
| 1990/11211 | char *auth; | |
| 1990/0227 | }bogus; | |
| 1991/0904 |
| |
| 1991/0901 | ||
| 1991/0904 |
| |
| 1991/0911 | 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); } | |
| 1991/0901 | } | |
| 1991/0904 |
| |
| 1991/0911 | 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); | |
| 1991/0904 | m->ref = 1; | |
| 1991/0911 | 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); | |
| 1990/0227 | unlock(m); | |
| 1991/0904 |
| |
| 1990/0604 | ||
| 1991/0904 |
| |
| 1991/0911 | return mattach(m, bogus.spec, bogus.auth); } | |
| 1990/0604 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0911 | 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; | |
| 1990/0227 | if(waserror()){ | |
| 1991/0904 |
| |
| 1991/0911 | mntfree(r); | |
| 1990/0227 | close(c); nexterror(); } | |
| 1991/0904 |
| |
| 1991/0911 | 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; | |
| 1990/0303 | c->mqid = c->qid; | |
| 1991/0904 |
| |
| 1990/0227 | poperror(); | |
| 1991/0911 | mntfree(r); | |
| 1990/0227 | return c; } | |
| 1991/0910/sys/src/9/port/devmnt.c:327,354 – 1991/0911/sys/src/9/port/devmnt.c:203,229 | ||
| 1990/0227 | mntclone(Chan *c, Chan *nc) { Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; int alloc = 0; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0911 | m = mntchk(c); r = mntralloc(); if(nc == 0) { | |
| 1990/0227 | nc = newchan(); | |
| 1991/0904 |
| |
| 1991/0911 | alloc = 1; | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1990/0227 | if(waserror()){ | |
| 1991/0904 |
| |
| 1991/0911 | mntfree(r); if(alloc) close(nc); | |
| 1990/0227 | nexterror(); } | |
| 1991/0904 |
| |
| 1991/0911 | r->request.type = Tclone; r->request.fid = c->fid; r->request.newfid = nc->fid; mountrpc(m, r); | |
| 1990/0227 | nc->type = c->type; nc->dev = c->dev; nc->qid = c->qid; | |
| 1991/0910/sys/src/9/port/devmnt.c:358,371 – 1991/0911/sys/src/9/port/devmnt.c:233,244 | ||
| 1990/0227 | nc->mnt = c->mnt; | |
| 1991/0427 | nc->mountid = c->mountid; | |
| 1991/0421 | nc->aux = c->aux; | |
| 1991/0904 |
| |
| 1990/0303 | nc->mchan = c->mchan; nc->mqid = c->qid; | |
| 1991/0904 |
| |
| 1991/0901 |
| |
| 1991/0904 |
| |
| 1991/0911 | poperror(); mntfree(r); | |
| 1990/0227 | return nc; } | |
| 1991/0910/sys/src/9/port/devmnt.c:373,397 – 1991/0911/sys/src/9/port/devmnt.c:246,269 | ||
| 1990/0227 | mntwalk(Chan *c, char *name) { Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); return 0; | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1991/0911 | r->request.type = Twalk; r->request.fid = c->fid; strncpy(r->request.name, name, NAMELEN); mountrpc(m, r); c->qid = r->reply.qid; | |
| 1990/0227 | poperror(); | |
| 1991/0904 |
| |
| 1991/0911 | mntfree(r); return 1; | |
| 1990/0227 | } void | |
| 1991/0910/sys/src/9/port/devmnt.c:398,421 – 1991/0911/sys/src/9/port/devmnt.c:270,291 | ||
| 1990/0227 | mntstat(Chan *c, char *dp) { Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); } | |
| 1991/0904 |
| |
| 1991/0911 | r->request.type = Tstat; r->request.fid = c->fid; mountrpc(m, r); memmove(dp, r->reply.stat, DIRLEN); mntdirfix((uchar*)dp, c); | |
| 1990/0227 | poperror(); | |
| 1991/0911 | mntfree(r); | |
| 1990/0227 | } Chan* | |
| 1991/0910/sys/src/9/port/devmnt.c:422,445 – 1991/0911/sys/src/9/port/devmnt.c:292,316 | ||
| 1990/0227 | mntopen(Chan *c, int omode) { Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); } | |
| 1991/0904 |
| |
| 1991/0911 | r->request.type = Topen; r->request.fid = c->fid; r->request.mode = omode; mountrpc(m, r); c->qid = r->reply.qid; | |
| 1990/0227 | c->offset = 0; c->mode = openmode(omode); c->flag |= COPEN; | |
| 1991/0911 | poperror(); mntfree(r); | |
| 1990/0227 | return c; } | |
| 1991/0910/sys/src/9/port/devmnt.c:447,472 – 1991/0911/sys/src/9/port/devmnt.c:318,343 | ||
| 1990/0227 | mntcreate(Chan *c, char *name, int omode, ulong perm) { Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); } | |
| 1991/0904 |
| |
| 1991/0911 | 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; | |
| 1990/0227 | c->flag |= COPEN; c->mode = openmode(omode); | |
| 1991/0904 |
| |
| 1991/0911 | poperror(); mntfree(r); | |
| 1990/0227 | } void | |
| 1991/0910/sys/src/9/port/devmnt.c:473,506 – 1991/0911/sys/src/9/port/devmnt.c:344,375 | ||
| 1990/0604 | mntclunk(Chan *c, int t) | |
| 1990/0227 | { Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | 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; } | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | r->request.type = t; r->request.fid = c->fid; mountrpc(m, r); nexterror(); | |
| 1990/0227 | } | |
| 1990/0604 | void | |
| 1991/0910/sys/src/9/port/devmnt.c:509,569 – 1991/0911/sys/src/9/port/devmnt.c:378,419 | ||
| 1990/0604 | mntclunk(c, Tclunk); } | |
| 1991/0904 |
| |
| 1991/0911 | void mntremove(Chan *c) | |
| 1990/0227 | { | |
| 1991/0911 | mntclunk(c, Tremove); } void mntwstat(Chan *c, char *dp) { | |
| 1990/0227 | Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | m = mntchk(c); r = mntralloc(); if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); } | |
| 1991/0904 |
| |
| 1991/0911 | r->request.type = Twstat; r->request.fid = c->fid; memmove(r->request.stat, dp, DIRLEN); mountrpc(m, r); | |
| 1990/0227 | poperror(); | |
| 1991/0904 |
| |
| 1991/0911 | mntfree(r); | |
| 1990/0227 | } long | |
| 1991/0411 | mntread(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1991/0911 | uchar *p, *e; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0911 | 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); | |
| 1990/0227 | return n; } | |
| 1991/0910/sys/src/9/port/devmnt.c:570,936 – 1991/0911/sys/src/9/port/devmnt.c:420,766 | ||
| 1990/0227 | long | |
| 1991/0411 | mntwrite(Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1991/0911 | return mntrdwr(Twrite, c, buf, n, offset); | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1991/0911 | long mntrdwr(int type, Chan *c, void *buf, long n, ulong offset) | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1990/0227 | Mnt *m; | |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc *r; ulong cnt, nr; char *uba; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1990/0227 |
| |
| 1991/0911 | 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; | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1990/0227 |
| |
| 1991/0911 | return cnt; | |
| 1990/0227 | } void | |
| 1991/0904 |
| |
| 1991/0911 | mountrpc(Mnt *m, Mntrpc *r) | |
| 1990/0604 | { | |
| 1991/0904 |
| |
| 1991/0911 | 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"); | |
| 1990/1123 | } } | |
| 1991/0904 |
| |
| 1990/1123 | void | |
| 1991/0904 |
| |
| 1991/0911 | mountio(Mnt *m, Mntrpc *r) | |
| 1990/1123 | { | |
| 1991/0904 |
| |
| 1991/0911 | int n; | |
| 1990/1124 | ||
| 1991/0904 |
| |
| 1991/0911 | 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); | |
| 1990/1124 | return; | |
| 1991/0808 | } | |
| 1990/1124 | ||
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | /* 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; | |
| 1990/1124 | } | |
| 1991/0904 |
| |
| 1991/0911 | m->rip = u->p; unlock(m); while(r->done == 0) { mntrpcread(m, r); mountmux(m, r); } mntgate(m); | |
| 1990/1124 | } void | |
| 1991/0904 |
| |
| 1991/0911 | mntrpcread(Mnt *m, Mntrpc *r) | |
| 1990/1124 | { | |
| 1991/0904 |
| |
| 1991/0911 | int n; | |
| 1990/0604 | ||
| 1991/0904 |
| |
| 1991/0911 | for(;;) { if(waserror()) { qunlock(&m->c->rdl); if(mntflush(m, r) == 0) { if(m->mux == 0) mntgate(m); nexterror(); } continue; | |
| 1990/0604 | } | |
| 1991/0904 |
| |
| 1991/0911 | 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; } | |
| 1990/0604 | } | |
| 1990/11211 | ||
| 1991/0904 |
| |
| 1991/0911 | void mntgate(Mnt *m) | |
| 1990/0717 | { | |
| 1991/0904 |
| |
| 1991/0911 | 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); | |
| 1990/0717 | } | |
| 1990/11211 | ||
| 1990/0604 | void | |
| 1991/0904 |
| |
| 1991/0911 | mountmux(Mnt *m, Mntrpc *r) | |
| 1990/0227 | { | |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | Mntrpc **l, *q; int done; char *dp; | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0911 | 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; | |
| 1991/0808 | } | |
| 1991/0904 |
| |
| 1991/0911 | 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; | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1991/0911 | unlock(m); return; | |
| 1990/0604 | ||
| 1991/0904 |
| |
| 1991/0911 | 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); | |
| 1990/0227 | } | |
| 1991/0904 |
| |
| 1991/0911 | } | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0911 | int mntflush(Mnt *m, Mntrpc *r) { Fcall flush; int n; | |
| 1990/0511 | ||
| 1991/0904 |
| |
| 1990/11211 |
| |
| 1991/0911 | r->flushtag++; if((r->flushtag-r->flushbase) == Flushspace) r->flushtag -= Flushspace; | |
| 1990/0511 | ||
| 1991/0904 |
| |
| 1991/0911 | 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; | |
| 1990/03081 | } | |
| 1991/0904 |
| |
| 1991/0911 | 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; } | |
| 1991/0901 | ||
| 1991/0904 |
| |
| 1991/0911 | Mntrpc * mntralloc(void) { Mntrpc *new; | |
| 1991/0901 | ||
| 1991/0904 |
| |
| 1991/0911 | 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"); | |
| 1991/0904 | } | |
| 1991/0911 | } 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; | |
| 1990/0703 | } | |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | l = &f->list; | |
| 1990/0227 | } | |
| 1991/0911 | unlock(m); } | |
| 1990/0227 | ||
| 1991/0904 |
| |
| 1991/0911 | Mnt * mntchk(Chan *c) { Mnt *m; m = &mntalloc.mntarena[c->mntindex]; if(m->id != c->dev) | |
| 1990/11211 | error(Eshutdown); | |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | return m; | |
| 1990/0717 | } | |
| 1990/1220 | void | |
| 1991/0911 | 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 | |
| 1991/0901 | mntdump(void) { | |
| 1991/0904 |
| |
| 1991/0911 | Mnt *me, *m; Mntrpc *re, *r; | |
| 1991/0901 | ||
| 1991/0904 |
| |
| 1991/0911 | me = &mntalloc.mntarena[conf.nmntdev]; for(m = mntalloc.mntarena; m < me; m++) { if(m->ref == 0) | |
| 1991/0904 | continue; | |
| 1991/0910 |
| |
| 1991/0904 |
| |
| 1991/0911 | 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"); | |
| 1991/0904 | } | |
| 1991/0911 | 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); | |
| 1991/0904 | } | |
| 1991/0911 | ||