From e0d8eaa4f337c08f8681a0a8d5c57676ac33f6a8 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 5 Jan 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-01-05 --- port/devmnt.c | 64 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/port/devmnt.c b/port/devmnt.c index ae0e141698bd528fca664370631364bcf223053e..3e2c97e3e836a79de60f58cdc7b4593103ecd3c7 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -18,6 +18,7 @@ struct Mntrpc 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 */ }; struct Mntalloc @@ -36,7 +37,8 @@ void mattach(Mnt*, Chan*, char*); void mntauth(Mnt*, Mntrpc*, char*, ushort); Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); -void mntflush(Mnt*, Mntrpc*); +Mntrpc* mntflushalloc(Mntrpc*); +void mntflushfree(Mnt*, Mntrpc*); void mntfree(Mntrpc*); void mntgate(Mnt*); void mntpntfree(Mnt*); @@ -633,6 +635,16 @@ mountio(Mnt *m, Mntrpc *r) { int n; + while(waserror()) { + if(m->rip == up) + mntgate(m); + if(strcmp(up->error, Eintr) != 0){ + mntflushfree(m, r); + nexterror(); + } + r = mntflushalloc(r); + } + lock(m); r->m = m; r->list = m->queue; @@ -643,14 +655,6 @@ mountio(Mnt *m, Mntrpc *r) n = convS2M(&r->request, r->rpc); if(n < 0) panic("bad message type in mountio"); - if(waserror()) { - if(m->rip == up) - mntgate(m); - if(strcmp(up->error, Eintr) != 0) - nexterror(); - mntflush(m, r); - return; - } if(devtab[m->c->type]->dc == L'M'){ if(mnt9prdwr(Twrite, m->c, r->rpc, n, 0) != n) error(Emountrpc); @@ -670,6 +674,7 @@ mountio(Mnt *m, Mntrpc *r) sleep(&r->r, rpcattn, r); if(r->done){ poperror(); + mntflushfree(m, r); return; } } @@ -681,6 +686,7 @@ mountio(Mnt *m, Mntrpc *r) } mntgate(m); poperror(); + mntflushfree(m, r); } void @@ -728,7 +734,7 @@ mountmux(Mnt *m, Mntrpc *r) lock(m); l = &m->queue; for(q = *l; q; q = q->list) { - // look for a reply to a message + /* look for a reply to a message */ if(q->request.tag == r->reply.tag) { *l = q->list; if(q != r) { @@ -756,8 +762,12 @@ mountmux(Mnt *m, Mntrpc *r) unlock(m); } -void -mntflush(Mnt *m, Mntrpc *r) +/* + * Create a new flush request and chain the previous + * requests from it + */ +Mntrpc* +mntflushalloc(Mntrpc *r) { Mntrpc *fr; @@ -768,13 +778,32 @@ mntflush(Mnt *m, Mntrpc *r) fr->request.oldtag = r->request.oldtag; else fr->request.oldtag = r->request.tag; + fr->flushed = r; + + return fr; +} - mountio(m, fr); - mntfree(fr); +/* + * 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; - if(!r->done){ - r->reply.type = Rflush; - mntqrm(m, r); + while(r){ + fr = r->flushed; + if(!r->done){ + r->reply.type = Rflush; + mntqrm(m, r); + } + if(fr) + mntfree(r); + r = fr; } } @@ -811,6 +840,7 @@ mntralloc(Chan *c) unlock(&mntalloc); new->c = c; new->done = 0; + new->flushed = nil; return new; }