| plan 9 kernel history: overview | file list | diff list |
2001/0819/port/devmnt.c (diff list | history)
| 2001/0808/sys/src/9/port/devmnt.c:5,10 – 2001/0819/sys/src/9/port/devmnt.c:5,21 (short | long | prev | next) | ||
| 1990/0227 | #include "fns.h" | |
| 1992/0111 | #include "../port/error.h" | |
| 1990/0227 | ||
| 2001/0819 | /* * 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. */ | |
| 2001/0527 | #define MAXRPC (IOHDRSZ+8192) | |
| 1991/0911 | struct Mntrpc | |
| 2001/0808/sys/src/9/port/devmnt.c:16,21 – 2001/0819/sys/src/9/port/devmnt.c:27,33 | ||
| 1995/0107 | Mnt* m; /* Mount device during rpc */ | |
| 1991/0911 | Rendez r; /* Place to hang out */ | |
| 2001/0527 | uchar* rpc; /* I/O Data buffer */ | |
| 2001/0819 | uint rpclen; /* len of buffer */ | |
| 2001/0619 | Block *b; /* reply blocks */ | |
| 1991/0911 | char done; /* Rpc completed */ | |
| 1998/0917 | uvlong stime; /* start time for mnt statistics */ | |
| 2001/0808/sys/src/9/port/devmnt.c:37,43 – 2001/0819/sys/src/9/port/devmnt.c:49,54 | ||
| 1991/0911 | }mntalloc; | |
| 1990/0227 | ||
| 2001/0527 | void mattach(Mnt*, Chan*, char*); | |
| 2001/0808 |
| |
| 2001/0527 | Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); Mntrpc* mntflushalloc(Mntrpc*, ulong); | |
| 2001/0808/sys/src/9/port/devmnt.c:53,62 – 2001/0819/sys/src/9/port/devmnt.c:64,73 | ||
| 2001/0527 | void mountmux(Mnt*, Mntrpc*); void mountrpc(Mnt*, Mntrpc*); int rpcattn(void*); | |
| 1990/0227 | ||
| 2001/0527 | char Esbadstat[] = "invalid directory entry received from server"; | |
| 2001/0819 | char Enoversion[] = "version not established for mount channel"; | |
| 2001/0527 | ||
| 1998/0917 | void (*mntstats)(int, Chan*, uvlong, ulong); | |
| 1994/0513 | ||
| 2001/0808/sys/src/9/port/devmnt.c:77,119 – 2001/0819/sys/src/9/port/devmnt.c:88,201 | ||
| 1993/1015 | cinit(); | |
| 1990/0604 | } | |
| 1997/0327 |
| |
| 1991/0911 |
| |
| 2001/0819 | /* * Version is not multiplexed: message sent only once per connection. */ long mntversion(Chan *c, char *version, int msize, int returnlen) | |
| 1990/0227 | { | |
| 2001/0819 | Fcall f; uchar *msg; | |
| 1992/0620 | Mnt *m; | |
| 2001/0601 |
| |
| 1990/0227 |
| |
| 1993/1015 |
| |
| 1990/0227 |
| |
| 2001/0819 | char *v; long k, l; uvlong oo; char buf[128]; | |
| 1990/0227 | ||
| 1991/0911 |
| |
| 1992/0620 |
| |
| 2001/0819 | qlock(&c->umqlock); /* make sure no one else does this until we've established ourselves */ if(waserror()){ qunlock(&c->umqlock); nexterror(); } | |
| 1992/0620 |
| |
| 1993/1016 |
| |
| 1991/0911 |
| |
| 1992/0620 |
| |
| 1991/0911 |
| |
| 1997/1205 |
| |
| 1993/0501 |
| |
| 2001/0527 |
| |
| 1993/0501 |
| |
| 1993/1016 |
| |
| 1993/0501 |
| |
| 1991/0911 |
| |
| 1998/0512 |
| |
| 2001/0819 | /* 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); | |
| 1991/0911 | } | |
| 2001/0819 | if(returnlen > 0){ if(returnlen < k) error(Eshort); memmove(version, buf, k); } return k; | |
| 1991/0901 | } | |
| 1993/1015 | ||
| 2001/0819 | 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); | |
| 1991/0911 | m = mntalloc.mntfree; | |
| 1992/0620 | if(m != 0) | |
| 1998/0512 | mntalloc.mntfree = m->list; | |
| 2001/0808/sys/src/9/port/devmnt.c:126,152 – 2001/0819/sys/src/9/port/devmnt.c:208,260 | ||
| 1992/0620 | } m->list = mntalloc.list; mntalloc.list = m; | |
| 2001/0819 | kstrdup(&m->version, f.version); | |
| 1991/0911 | m->id = mntalloc.id++; | |
| 2001/0619 | m->q = qopen(10*MAXRPC, 0, nil, nil); | |
| 1991/0911 | unlock(&mntalloc); | |
| 1992/0620 | ||
| 2001/0819 | poperror(); /* msg */ free(msg); | |
| 1997/1205 | lock(m); | |
| 1991/0904 |
| |
| 1991/0911 | m->queue = 0; m->rip = 0; | |
| 2001/0819 | c->flag |= CMSG; c->mux = m; | |
| 1992/0620 | m->c = c; | |
| 1991/1011 |
| |
| 2001/0527 |
| |
| 1993/1016 |
| |
| 2001/0819 | unlock(m); | |
| 1991/0911 |
| |
| 2001/0819 | poperror(); /* c */ qunlock(&c->umqlock); | |
| 1993/0501 | ||
| 1990/0227 |
| |
| 2001/0819 | k = strlen(f.version); if(returnlen > 0){ if(returnlen < k) error(Eshort); memmove(version, f.version, k); } | |
| 1990/0604 | ||
| 2001/0819 | 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); } | |
| 1993/0501 | c = mntchan(); | |
| 1992/0320 | if(waserror()) { | |
| 1993/0501 |
| |
| 2001/0527 | /* Close must not be called since it will * call mnt recursively */ | |
| 2001/0808/sys/src/9/port/devmnt.c:154,188 – 2001/0819/sys/src/9/port/devmnt.c:262,330 | ||
| 1992/0320 | nexterror(); } | |
| 1993/0501 |
| |
| 2001/0819 | r = mntralloc(0, m->c->iounit); | |
| 1993/0321 | ||
| 1993/1016 |
| |
| 2001/0819 | if(waserror()) { mntfree(r); nexterror(); } | |
| 1993/1016 | ||
| 1992/0320 |
| |
| 1991/0911 |
| |
| 2001/0819 | r->request.type = Tauth; r->request.afid = c->fid; r->request.uname = up->user; r->request.aname = spec; mountrpc(m, r); | |
| 1990/0604 | ||
| 2001/0527 |
| |
| 1993/0501 |
| |
| 1991/0911 |
| |
| 2001/0819 | c->qid = r->reply.aqid; c->mchan = m->c; incref(m->c); c->mqid = c->qid; c->mode = ORDWR; | |
| 1991/0911 | ||
| 2001/0527 |
| |
| 1991/0918 |
| |
| 2001/0819 | poperror(); /* r */ mntfree(r); | |
| 1993/0501 | ||
| 2001/0819 | poperror(); /* c */ | |
| 1993/0501 | return c; | |
| 2001/0819 | ||
| 1993/0501 | } | |
| 2001/0527 |
| |
| 1993/0501 |
| |
| 2001/0819 | static Chan* mntattach(char *muxattach) | |
| 1993/0501 | { | |
| 2001/0819 | Mnt *m; Chan *c; | |
| 1993/0501 | Mntrpc *r; | |
| 2001/0819 | struct bogus{ Chan *chan; Chan *authchan; char *spec; int flags; }bogus; | |
| 1993/0501 | ||
| 2001/0819 | 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(); } | |
| 2001/0527 | r = mntralloc(0, m->c->iounit); | |
| 1992/0620 |
| |
| 1991/0911 | ||
| 1994/1212 | if(waserror()) { | |
| 1992/0314 | mntfree(r); | |
| 2001/0808/sys/src/9/port/devmnt.c:191,210 – 2001/0819/sys/src/9/port/devmnt.c:333,376 | ||
| 1992/0314 | ||
| 1991/0911 | r->request.type = Tattach; r->request.fid = c->fid; | |
| 2001/0819 | if(bogus.authchan == nil) r->request.afid = NOFID; else r->request.afid = bogus.authchan->fid; | |
| 2001/0527 | r->request.uname = up->user; | |
| 2001/0808 |
| |
| 2001/0819 | r->request.aname = bogus.spec; | |
| 1991/0911 | mountrpc(m, r); c->qid = r->reply.qid; c->mchan = m->c; | |
| 2001/0819 | incref(m->c); | |
| 1990/0303 | c->mqid = c->qid; | |
| 1993/0501 | ||
| 1990/0227 |
| |
| 2001/0819 | poperror(); /* r */ | |
| 1991/0911 | mntfree(r); | |
| 2001/0819 | poperror(); /* c */ if(bogus.flags&MCACHE) c->flag |= CCACHE; return c; | |
| 1992/0318 | } | |
| 2001/0819 | 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; } | |
| 2001/0527 | static Walkqid* mntwalk(Chan *c, Chan *nc, char **name, int nname) | |
| 1990/0227 | { | |
| 2001/0808/sys/src/9/port/devmnt.c:213,218 – 2001/0819/sys/src/9/port/devmnt.c:379,386 | ||
| 1991/0911 | Mntrpc *r; | |
| 2001/0527 | Walkqid *wq; | |
| 2001/0601 | ||
| 2001/0819 | if(nc != nil) print("mntwalk: nc != nil\n"); | |
| 2001/0527 | if(nname > MAXWELEM) error("devmnt: too many name elements"); alloc = 0; | |
| 2001/0808/sys/src/9/port/devmnt.c:268,274 – 2001/0819/sys/src/9/port/devmnt.c:436,443 | ||
| 2001/0527 | if(wq->clone != nil){ if(wq->clone != c){ wq->clone->type = c->type; | |
| 2001/0819 | wq->clone->mchan = c->mchan; incref(c->mchan); | |
| 2001/0527 | } if(r->reply.nwqid > 0) wq->clone->qid = r->reply.wqid[r->reply.nwqid-1]; | |
| 2001/0808/sys/src/9/port/devmnt.c:377,383 – 2001/0819/sys/src/9/port/devmnt.c:546,551 | ||
| 2001/0527 | r = mntralloc(c, m->c->iounit); | |
| 1991/0911 | if(waserror()){ | |
| 1993/0501 | mntfree(r); | |
| 1991/1004 | nexterror(); | |
| 1991/0911 | } | |
| 1990/0227 | ||
| 2001/0808/sys/src/9/port/devmnt.c:385,408 – 2001/0819/sys/src/9/port/devmnt.c:553,571 | ||
| 1991/0911 | r->request.fid = c->fid; mountrpc(m, r); | |
| 1993/0501 | mntfree(r); | |
| 1991/1004 | poperror(); } | |
| 2001/0527 | void | |
| 1999/0714 |
| |
| 2001/0819 | muxclose(Mnt *m) | |
| 1991/1004 | { | |
| 1993/0321 | Mntrpc *q, *r; | |
| 1991/1004 | ||
| 1993/0321 |
| |
| 1997/0327 |
| |
| 1993/0321 | mntpntfree(m); } | |
| 2001/0808/sys/src/9/port/devmnt.c:853,863 – 2001/0819/sys/src/9/port/devmnt.c:1016,1038 | ||
| 1999/0212 | unlock(&mntalloc); | |
| 1992/0620 | exhausted("mount rpc buffer"); | |
| 1991/0911 | } | |
| 2001/0819 | new->rpclen = iounit; | |
| 1992/0620 | new->request.tag = mntalloc.rpctag++; | |
| 1991/0904 | } | |
| 1999/0212 | else { mntalloc.rpcfree = new->list; mntalloc.nrpcfree--; | |
| 2001/0819 | 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; } | |
| 1999/0212 | } mntalloc.nrpcused++; | |
| 1992/0620 | unlock(&mntalloc); | |
| 2001/0808/sys/src/9/port/devmnt.c:911,923 – 2001/0819/sys/src/9/port/devmnt.c:1086,1106 | ||
| 1991/0911 | { Mnt *m; | |
| 1992/0620 |
| |
| 2001/0819 | /* This routine is mostly vestiges of prior lives; now it's just sanity checking */ | |
| 1993/0501 | ||
| 2001/0819 | 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)); | |
| 1993/0501 | /* | |
| 2001/0819 | * Was it closed and reused (was error(Eshutdown); now, it can't happen) | |
| 1993/0501 | */ if(m->id == 0 || m->id >= c->dev) | |
| 1990/11211 |
| |
| 2001/0819 | panic("mntchk 3: can't happen"); | |
| 1993/0501 | ||
| 1991/0911 | return m; | |
| 1990/0717 | } | |