X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fport%2Fdevmnt.c;h=cce379095e4835cea192b04b114107ba3c8e9a75;hb=40b6959788d35d66c5d4580730ac294f0d4c34f4;hp=adb65155bc3d46963e70156f07a35df60f84dee2;hpb=ea5a23d39a5a5313144055481e85689809d65673;p=plan9front.git diff --git a/sys/src/9/port/devmnt.c b/sys/src/9/port/devmnt.c index adb65155b..cce379095 100644 --- a/sys/src/9/port/devmnt.c +++ b/sys/src/9/port/devmnt.c @@ -25,15 +25,15 @@ struct Mntrpc Fcall request; /* Outgoing file system protocol message */ Fcall reply; /* Incoming reply */ Mnt* m; /* Mount device during rpc */ - Rendez r; /* Place to hang out */ + Rendez* z; /* Place to hang out */ uchar* rpc; /* I/O Data buffer */ uint rpclen; /* len of buffer */ - Block *b; /* reply blocks */ - char done; /* Rpc completed */ + Block* b; /* reply blocks */ uvlong stime; /* start time for mnt statistics */ ulong reqlen; /* request length for mnt statistics */ ulong replen; /* reply length for mnt statistics */ Mntrpc* flushed; /* message this one flushes */ + char done; /* Rpc completed */ }; enum @@ -58,10 +58,9 @@ struct Mntalloc Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); Mntrpc* mntflushalloc(Mntrpc*, ulong); -void mntflushfree(Mnt*, Mntrpc*); +Mntrpc* 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); @@ -75,8 +74,8 @@ Chan* mntchan(void); char Esbadstat[] = "invalid directory entry received from server"; char Enoversion[] = "version not established for mount channel"; +void (*mntstats)(int, Chan*, uvlong, ulong); -void (*mntstats)(int, Chan*, uvlong, ulong); static void mntreset(void) @@ -101,6 +100,7 @@ mntversion(Chan *c, char *version, int msize, int returnlen) uchar *msg; Mnt *m; char *v; + Queue *q; long k, l; uvlong oo; char buf[128]; @@ -199,6 +199,16 @@ mntversion(Chan *c, char *version, int msize, int returnlen) k = strlen(f.version); if(strncmp(f.version, v, k) != 0) error("bad 9P version returned from server"); + if(returnlen > 0 && returnlen < k) + error(Eshort); + + v = nil; + kstrdup(&v, f.version); + q = qopen(10*MAXRPC, 0, nil, nil); + if(q == nil){ + free(v); + exhausted("mount queues"); + } /* now build Mnt associated with this connection */ lock(&mntalloc); @@ -208,24 +218,22 @@ mntversion(Chan *c, char *version, int msize, int returnlen) else { m = malloc(sizeof(Mnt)); if(m == 0) { + qfree(q); + free(v); unlock(&mntalloc); exhausted("mount devices"); } } m->list = mntalloc.list; mntalloc.list = m; - m->version = nil; - kstrdup(&m->version, f.version); + m->version = v; m->id = mntalloc.id++; - m->q = qopen(10*MAXRPC, 0, nil, nil); + m->q = q; m->msize = f.msize; unlock(&mntalloc); - if(returnlen > 0){ - if(returnlen < k) - error(Eshort); - memmove(version, f.version, k); - } + if(returnlen > 0) + memmove(version, f.version, k); /* length was checked above */ poperror(); /* msg */ free(msg); @@ -564,23 +572,18 @@ mntclunk(Chan *c, int t) void muxclose(Mnt *m) { - Mntrpc *q, *r; + Mnt *f, **l; + Mntrpc *r; - for(q = m->queue; q; q = r) { - r = q->list; - mntfree(q); + while((r = m->queue) != nil){ + m->queue = r->list; + mntfree(r); } m->id = 0; free(m->version); m->version = nil; - mntpntfree(m); -} - -void -mntpntfree(Mnt *m) -{ - Mnt *f, **l; - Queue *q; + qfree(m->q); + m->q = nil; lock(&mntalloc); l = &mntalloc.list; @@ -593,10 +596,7 @@ mntpntfree(Mnt *m) } m->list = mntalloc.mntfree; mntalloc.mntfree = m; - q = m->q; unlock(&mntalloc); - - qfree(q); } static void @@ -777,13 +777,21 @@ mountio(Mnt *m, Mntrpc *r) if(m->rip == up) mntgate(m); if(strcmp(up->errstr, Eintr) != 0){ - mntflushfree(m, r); + r = mntflushfree(m, r); + switch(r->request.type){ + case Tremove: + case Tclunk: + /* botch, abandon fid */ + if(strcmp(up->errstr, Ehungup) != 0) + r->c->fid = 0; + } nexterror(); } r = mntflushalloc(r, m->msize); } lock(m); + r->z = &up->sleep; r->m = m; r->list = m->queue; m->queue = r; @@ -793,8 +801,12 @@ mountio(Mnt *m, Mntrpc *r) if(m->msize == 0) panic("msize"); n = convS2M(&r->request, r->rpc, m->msize); - if(n < 0) - panic("bad message type in mountio"); + if(n <= 0){ + print("mountio: proc %s %lud: convS2M returned %d for tag %d fid %d T%d\n", + up->text, up->pid, n, r->request.tag, r->request.fid, r->request.type); + error(Emountrpc); + } + if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) error(Emountrpc); r->stime = fastticks(nil); @@ -806,7 +818,7 @@ mountio(Mnt *m, Mntrpc *r) if(m->rip == 0) break; unlock(m); - sleep(&r->r, rpcattn, r); + sleep(r->z, rpcattn, r); if(r->done){ poperror(); mntflushfree(m, r); @@ -924,7 +936,7 @@ mntgate(Mnt *m) m->rip = 0; for(q = m->queue; q; q = q->list) { if(q->done == 0) - if(wakeup(&q->r)) + if(wakeup(q->z)) break; } unlock(m); @@ -934,6 +946,7 @@ void mountmux(Mnt *m, Mntrpc *r) { Mntrpc **l, *q; + Rendez *z; lock(m); l = &m->queue; @@ -941,6 +954,10 @@ mountmux(Mnt *m, Mntrpc *r) /* look for a reply to a message */ if(q->request.tag == r->reply.tag) { *l = q->list; + if(mntstats != nil) + (*mntstats)(q->request.type, + m->c, q->stime, + q->reqlen + r->replen); if(q != r) { /* * Completed someone else. @@ -949,15 +966,13 @@ mountmux(Mnt *m, Mntrpc *r) q->reply = r->reply; q->b = r->b; r->b = nil; - } - q->done = 1; + z = q->z; + } else + z = nil; + q->done = 1; /* hands off */ + if(z != nil) + wakeup(z); unlock(m); - if(mntstats != nil) - (*mntstats)(q->request.type, - m->c, q->stime, - q->reqlen + r->replen); - if(q != r) - wakeup(&q->r); return; } l = &q->list; @@ -992,9 +1007,9 @@ mntflushalloc(Mntrpc *r, ulong iounit) * 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. + * Rflush. Return the original rpc. */ -void +Mntrpc* mntflushfree(Mnt *m, Mntrpc *r) { Mntrpc *fr; @@ -1005,10 +1020,12 @@ mntflushfree(Mnt *m, Mntrpc *r) r->reply.type = Rflush; mntqrm(m, r); } - if(fr) - mntfree(r); + if(fr == nil) + break; + mntfree(r); r = fr; } + return r; } int @@ -1134,7 +1151,7 @@ mntchk(Chan *c) /* This routine is mostly vestiges of prior lives; now it's just sanity checking */ if(c->mchan == nil) - panic("mntchk 1: nil mchan c %s\n", chanpath(c)); + panic("mntchk 1: nil mchan c %s", chanpath(c)); m = c->mchan->mux;