| plan 9 kernel history: overview | file list | diff list |
1993/0501/port/devmnt.c (diff list | history)
| 1993/0417/sys/src/9/port/devmnt.c:6,14 – 1993/0501/sys/src/9/port/devmnt.c:6,14 (short | long | prev | next) | ||
| 1992/0111 | #include "../port/error.h" | |
| 1990/0227 | #include "devtab.h" | |
| 1991/0911 |
| |
| 1990/0227 | { | |
| 1993/0501 | Chan *c; /* Channel for whom we are working */ | |
| 1991/0911 | Mntrpc *list; /* Free/pending list */ Fcall request; /* Outgoing file system protocol message */ Fcall reply; /* Incoming reply */ | |
| 1993/0417/sys/src/9/port/devmnt.c:21,44 – 1993/0501/sys/src/9/port/devmnt.c:21,30 | ||
| 1991/0911 | char flush[MAXMSG]; /* Somewhere to build flush */ | |
| 1990/0227 | }; | |
| 1991/0911 |
| |
| 1990/0604 |
| |
| 1991/0911 |
| |
| 1993/0321 |
| |
| 1991/0926 |
| |
| 1992/0305 |
| |
| 1990/0604 |
| |
| 1991/0911 | struct Mntalloc | |
| 1990/0227 | { Lock; | |
| 1992/0620 |
| |
| 1993/0501 | Mnt *list; /* Mount devices in use */ | |
| 1992/0620 | Mnt *mntfree; /* Free list */ | |
| 1991/0911 | Mntrpc *rpcfree; int id; | |
| 1993/0417/sys/src/9/port/devmnt.c:48,63 – 1993/0501/sys/src/9/port/devmnt.c:34,49 | ||
| 1992/0613 | #define MAXRPC (MAXFDATA+MAXMSG) | |
| 1991/0911 | #define limit(n, max) (n > max ? max : n) | |
| 1990/0227 | ||
| 1993/0330 |
| |
| 1993/0501 | void mattach(Mnt*, Chan*, char*); void mntauth(Mnt *, Mntrpc *, char *, ushort); | |
| 1992/0825 | Mnt* mntchk(Chan*); | |
| 1991/0911 | void mntdirfix(uchar*, Chan*); | |
| 1991/1004 |
| |
| 1992/0825 | int mntflush(Mnt*, Mntrpc*); void mntfree(Mntrpc*); void mntgate(Mnt*); | |
| 1992/0320 | void mntpntfree(Mnt*); | |
| 1992/0825 | void mntqrm(Mnt*, Mntrpc*); | |
| 1993/0501 | Mntrpc* mntralloc(Chan*); | |
| 1992/0825 | long mntrdwr(int , Chan*, void*,long , ulong); void mntrpcread(Mnt*, Mntrpc*); void mountio(Mnt*, Mntrpc*); | |
| 1993/0417/sys/src/9/port/devmnt.c:64,70 – 1993/0501/sys/src/9/port/devmnt.c:50,58 | ||
| 1992/0825 | void mountmux(Mnt*, Mntrpc*); void mountrpc(Mnt*, Mntrpc*); int rpcattn(Mntrpc*); | |
| 1993/0321 |
| |
| 1993/0501 | void mclose(Mnt*, Chan*); void mntrecover(Mnt*, Mntrpc*); Chan* mntchan(void); | |
| 1990/0227 | ||
| 1991/0911 | enum | |
| 1990/0303 | { | |
| 1993/0417/sys/src/9/port/devmnt.c:92,100 – 1993/0501/sys/src/9/port/devmnt.c:80,90 | ||
| 1990/0227 | { | |
| 1992/0620 | Mnt *m; | |
| 1993/0321 | Chan *c, *mc; | |
| 1993/0501 | char buf[NAMELEN]; | |
| 1990/0227 | struct bogus{ Chan *chan; char *spec; | |
| 1993/0501 | char recov; | |
| 1990/0227 | }bogus; | |
| 1991/0911 | bogus = *((struct bogus *)muxattach); | |
| 1993/0417/sys/src/9/port/devmnt.c:108,119 – 1993/0501/sys/src/9/port/devmnt.c:98,115 | ||
| 1992/0620 | unlock(&mntalloc); | |
| 1991/0911 | m->ref++; unlock(m); | |
| 1993/0330 |
| |
| 1993/0501 | c = mntchan(); if(waserror()) { chanfree(c); nexterror(); } mattach(m, c, bogus.spec); poperror(); return c; | |
| 1991/0911 | } unlock(m); } | |
| 1991/0901 | } | |
| 1993/0321 | ||
| 1991/0911 | m = mntalloc.mntfree; | |
| 1992/0620 | if(m != 0) mntalloc.mntfree = m->list; | |
| 1993/0417/sys/src/9/port/devmnt.c:137,143 – 1993/0501/sys/src/9/port/devmnt.c:133,140 | ||
| 1991/0911 | m->rip = 0; | |
| 1992/0620 | m->c = c; | |
| 1991/1011 | m->c->flag |= CMSG; | |
| 1992/0915 |
| |
| 1993/0501 | m->blocksize = MAXFDATA; /**/ m->recov = bogus.recov; | |
| 1991/0911 | switch(devchar[m->c->type]) { default: | |
| 1993/0417/sys/src/9/port/devmnt.c:148,208 – 1993/0501/sys/src/9/port/devmnt.c:145,214 | ||
| 1992/0317 | break; | |
| 1991/0911 | } incref(m->c); | |
| 1993/0501 | sprint(buf, "#M%d", m->id); m->tree.root = ptenter(&m->tree, 0, buf); | |
| 1990/0227 | unlock(m); | |
| 1990/0604 | ||
| 1993/0501 | c = mntchan(); | |
| 1992/0320 | if(waserror()) { | |
| 1993/0321 |
| |
| 1993/0501 | mclose(m, c); /* Close must not be called since it will * call mnt recursively */ chanfree(c); | |
| 1992/0320 | nexterror(); } | |
| 1993/0330 |
| |
| 1993/0501 | mattach(m, c, bogus.spec); poperror(); | |
| 1993/0321 | ||
| 1993/0330 |
| |
| 1993/0321 | mc = m->c; | |
| 1993/0323 | if(mc->type == devno('M', 0) && (c->qid.path&CHDIR) == 0) { | |
| 1993/0501 | mclose(m, c); | |
| 1993/0323 | c->qid.path |= CHDIR; | |
| 1993/0321 | c->mntptr = mc->mntptr; | |
| 1993/0323 |
| |
| 1993/0501 | c->mchan = c->mntptr->c; | |
| 1993/0321 | c->mqid = c->qid; | |
| 1993/0501 | c->path = c->mntptr->tree.root; incref(c->path); | |
| 1993/0321 | incref(c->mntptr); | |
| 1992/0320 |
| |
| 1991/0911 | } | |
| 1990/0604 | ||
| 1991/0911 |
| |
| 1993/0330 |
| |
| 1993/0501 | Chan* mntchan(void) | |
| 1991/0911 | { Chan *c; | |
| 1993/0330 |
| |
| 1991/0911 |
| |
| 1993/0501 | c = devattach('M', 0); | |
| 1991/0918 | lock(&mntalloc); c->dev = mntalloc.id++; unlock(&mntalloc); | |
| 1993/0501 | return c; } void mattach(Mnt *m, Chan *c, char *spec) { ulong id; Mntrpc *r; r = mntralloc(0); | |
| 1992/0620 | c->mntptr = m; | |
| 1991/0911 | ||
| 1992/0314 | if(waserror()){ mntfree(r); | |
| 1993/0403 |
| |
| 1992/0320 |
| |
| 1992/0314 | nexterror(); } | |
| 1991/0911 | r->request.type = Tattach; r->request.fid = c->fid; | |
| 1993/0404 |
| |
| 1993/0501 | memmove(r->request.uname, up->user, NAMELEN); | |
| 1991/0911 | strncpy(r->request.aname, spec, NAMELEN); | |
| 1993/0330 | id = authrequest(m->c->session, &r->request); | |
| 1991/0911 | mountrpc(m, r); | |
| 1993/0417/sys/src/9/port/devmnt.c:211,219 – 1993/0501/sys/src/9/port/devmnt.c:217,227 | ||
| 1991/0911 | c->qid = r->reply.qid; c->mchan = m->c; | |
| 1990/0303 | c->mqid = c->qid; | |
| 1993/0501 | c->path = m->tree.root; incref(c->path); | |
| 1990/0227 | poperror(); | |
| 1991/0911 | mntfree(r); | |
| 1990/0227 |
| |
| 1992/0318 | } | |
| 1990/0227 | Chan* | |
| 1993/0417/sys/src/9/port/devmnt.c:224,230 – 1993/0501/sys/src/9/port/devmnt.c:232,238 | ||
| 1991/0911 | int alloc = 0; | |
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(nc == 0) { | |
| 1990/0227 | nc = newchan(); | |
| 1991/0911 | alloc = 1; | |
| 1993/0417/sys/src/9/port/devmnt.c:255,264 – 1993/0501/sys/src/9/port/devmnt.c:263,273 | ||
| 1990/0227 | mntwalk(Chan *c, char *name) { Mnt *m; | |
| 1993/0501 | Path *op; | |
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(waserror()) { mntfree(r); return 0; | |
| 1993/0417/sys/src/9/port/devmnt.c:269,274 – 1993/0501/sys/src/9/port/devmnt.c:278,292 | ||
| 1991/0911 | mountrpc(m, r); c->qid = r->reply.qid; | |
| 1993/0501 | 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); | |
| 1991/0911 | ||
| 1990/0227 | poperror(); | |
| 1991/0911 | mntfree(r); | |
| 1993/0417/sys/src/9/port/devmnt.c:282,288 – 1993/0501/sys/src/9/port/devmnt.c:300,306 | ||
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); | |
| 1993/0417/sys/src/9/port/devmnt.c:304,310 – 1993/0501/sys/src/9/port/devmnt.c:322,328 | ||
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); | |
| 1993/0417/sys/src/9/port/devmnt.c:330,336 – 1993/0501/sys/src/9/port/devmnt.c:348,354 | ||
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); | |
| 1993/0417/sys/src/9/port/devmnt.c:356,364 – 1993/0501/sys/src/9/port/devmnt.c:374,383 | ||
| 1991/1004 | Mntrpc *r; | |
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(waserror()){ | |
| 1991/1004 |
| |
| 1993/0501 | mntfree(r); mclose(m, c); | |
| 1991/1004 | nexterror(); | |
| 1991/0911 | } | |
| 1990/0227 | ||
| 1993/0417/sys/src/9/port/devmnt.c:365,376 – 1993/0501/sys/src/9/port/devmnt.c:384,396 | ||
| 1991/0911 | r->request.type = t; r->request.fid = c->fid; mountrpc(m, r); | |
| 1991/1004 |
| |
| 1993/0501 | mntfree(r); mclose(m, c); | |
| 1991/1004 | poperror(); } void | |
| 1993/0321 |
| |
| 1993/0501 | mclose(Mnt *m, Chan *c) | |
| 1991/1004 | { | |
| 1993/0321 | Mntrpc *q, *r; | |
| 1991/1004 | ||
| 1993/0417/sys/src/9/port/devmnt.c:377,382 – 1993/0501/sys/src/9/port/devmnt.c:397,405 | ||
| 1993/0321 | if(decref(m) != 0) return; | |
| 1993/0501 | c->path = 0; ptclose(&m->tree); | |
| 1993/0321 | for(q = m->queue; q; q = r) { r = q->list; q->flushed = 0; | |
| 1993/0417/sys/src/9/port/devmnt.c:388,400 – 1993/0501/sys/src/9/port/devmnt.c:411,416 | ||
| 1993/0321 | } void | |
| 1992/0320 |
| |
| 1992/0620 | Mnt *f, **l; | |
| 1993/0417/sys/src/9/port/devmnt.c:433,439 – 1993/0501/sys/src/9/port/devmnt.c:449,455 | ||
| 1991/0911 | Mntrpc *r; | |
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); | |
| 1993/0501 | r = mntralloc(c); | |
| 1991/0911 | if(waserror()) { mntfree(r); | |
| 1990/0227 | nexterror(); | |
| 1993/0417/sys/src/9/port/devmnt.c:475,483 – 1993/0501/sys/src/9/port/devmnt.c:491,498 | ||
| 1990/0227 | ||
| 1991/0911 | m = mntchk(c); uba = buf; | |
| 1993/0417 |
| |
| 1991/0911 |
| |
| 1993/0501 | for(cnt = 0; n; n -= nr) { r = mntralloc(c); | |
| 1991/0911 | if(waserror()) { mntfree(r); nexterror(); | |
| 1993/0417/sys/src/9/port/devmnt.c:496,503 – 1993/0501/sys/src/9/port/devmnt.c:511,517 | ||
| 1991/0911 | offset += nr; uba += nr; cnt += nr; | |
| 1993/0417 |
| |
| 1993/0501 | if(nr != r->request.count) | |
| 1991/0911 | break; | |
| 1990/0227 | } | |
| 1991/0911 | return cnt; | |
| 1993/0417/sys/src/9/port/devmnt.c:506,526 – 1993/0501/sys/src/9/port/devmnt.c:520,550 | ||
| 1990/0227 | void | |
| 1991/0911 | mountrpc(Mnt *m, Mntrpc *r) | |
| 1990/0604 | { | |
| 1992/0620 |
| |
| 1993/0501 | int t; r->reply.tag = 0; | |
| 1992/0613 | r->reply.type = 4; | |
| 1992/0620 | ||
| 1993/0501 | while(waserror()) { if(m->recov == 0) nexterror(); mntrecover(m, r); } | |
| 1991/0911 | mountio(m, r); | |
| 1992/0112 |
| |
| 1993/0501 | poperror(); | |
| 1992/0620 | ||
| 1991/0911 |
| |
| 1993/0501 | t = r->reply.type; switch(t) { case Rerror: error(r->reply.ename); case Rflush: | |
| 1992/0111 | error(Eintr); | |
| 1991/0911 |
| |
| 1992/0620 |
| |
| 1993/0501 | 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); | |
| 1992/0113 | error(Emountrpc); | |
| 1990/1123 | } } | |
| 1993/0417/sys/src/9/port/devmnt.c:570,576 – 1993/0501/sys/src/9/port/devmnt.c:594,600 | ||
| 1991/0911 | if(r->done) return; | |
| 1990/1124 | } | |
| 1991/0911 |
| |
| 1993/0501 | m->rip = up; | |
| 1991/0911 | unlock(m); while(r->done == 0) { mntrpcread(m, r); | |
| 1993/0417/sys/src/9/port/devmnt.c:612,618 – 1993/0501/sys/src/9/port/devmnt.c:636,642 | ||
| 1991/0911 | lock(m); m->rip = 0; | |
| 1993/0501 | for(q = m->queue; q; q = q->list) { | |
| 1991/0911 | if(q->done == 0) { lock(&q->r); if(q->r.p) { | |
| 1993/0417/sys/src/9/port/devmnt.c:623,628 – 1993/0501/sys/src/9/port/devmnt.c:647,653 | ||
| 1991/0911 | } unlock(&q->r); } | |
| 1993/0501 | } | |
| 1991/0911 | unlock(m); | |
| 1990/0717 | } | |
| 1990/11211 | ||
| 1993/0417/sys/src/9/port/devmnt.c:643,649 – 1993/0501/sys/src/9/port/devmnt.c:668,674 | ||
| 1992/0305 | dp = q->rpc; q->rpc = r->rpc; r->rpc = dp; | |
| 1993/0501 | q->reply = r->reply; | |
| 1992/0305 | q->done = 1; wakeup(&q->r); }else | |
| 1993/0417/sys/src/9/port/devmnt.c:674,680 – 1993/0501/sys/src/9/port/devmnt.c:699,705 | ||
| 1991/0911 | n = convS2M(&flush, r->flush); if(waserror()) { | |
| 1992/0111 |
| |
| 1993/0501 | if(strcmp(up->error, Eintr) == 0) | |
| 1991/0911 | return 1; mntqrm(m, r); return 0; | |
| 1993/0417/sys/src/9/port/devmnt.c:685,691 – 1993/0501/sys/src/9/port/devmnt.c:710,716 | ||
| 1991/0911 | } | |
| 1991/0901 | ||
| 1991/0911 | Mntrpc * | |
| 1993/0501 | mntralloc(Chan *c) | |
| 1991/0911 | { Mntrpc *new; | |
| 1991/0901 | ||
| 1993/0417/sys/src/9/port/devmnt.c:703,708 – 1993/0501/sys/src/9/port/devmnt.c:728,734 | ||
| 1992/0620 | new->request.tag = mntalloc.rpctag++; | |
| 1991/0904 | } | |
| 1992/0620 | unlock(&mntalloc); | |
| 1993/0501 | new->c = c; | |
| 1992/0620 | new->done = 0; new->flushed = 0; return new; | |
| 1993/0417/sys/src/9/port/devmnt.c:737,742 – 1993/0501/sys/src/9/port/devmnt.c:763,820 | ||
| 1991/0911 | unlock(m); } | |
| 1990/0227 | ||
| 1993/0501 | 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); } | |
| 1991/0911 | Mnt * mntchk(Chan *c) { | |
| 1993/0417/sys/src/9/port/devmnt.c:743,751 – 1993/0501/sys/src/9/port/devmnt.c:821,839 | ||
| 1991/0911 | Mnt *m; | |
| 1992/0620 | m = c->mntptr; | |
| 1991/0918 |
| |
| 1992/0620 |
| |
| 1993/0501 | /* * Was it closed and reused */ if(m->id == 0 || m->id >= c->dev) | |
| 1990/11211 | error(Eshutdown); | |
| 1993/0501 | /* * Try and get the channel back */ if((c->flag&CRECOV) && m->recprog == 0) recoverchan(m, c); | |
| 1991/0911 | return m; | |
| 1990/0717 | } | |
| 1993/0417/sys/src/9/port/devmnt.c:762,765 – 1993/0501/sys/src/9/port/devmnt.c:850,954 | ||
| 1991/0911 | rpcattn(Mntrpc *r) { return r->done || r->m->rip == 0; | |
| 1993/0501 | } 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); | |
| 1991/0911 | } | |