From 6bd82b34fd6ff8955ff372c1e84ec94e80ddf98a Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 27 Apr 2012 17:51:20 +0200 Subject: [PATCH] async clunk for cached mounts, fix closeproc explosion --- rc/bin/9fs | 6 +-- sys/src/9/port/chan.c | 107 +++++++++++++++++++++------------------ sys/src/9/port/sysfile.c | 2 +- 3 files changed, 62 insertions(+), 53 deletions(-) diff --git a/rc/bin/9fs b/rc/bin/9fs index 47b4083e6..8f38872e8 100755 --- a/rc/bin/9fs +++ b/rc/bin/9fs @@ -37,13 +37,13 @@ case other case juke # ye olde file server srv -q il!jukefs && mount /srv/il!jukefs /n/juke case sources - srv -nq tcp!sources.cs.bell-labs.com sources /n/sources + srv -nqC tcp!sources.cs.bell-labs.com sources /n/sources case sourcesdump 9fs sources - mount -n /srv/sources /n/sourcesdump main/archive + mount -nC /srv/sources /n/sourcesdump main/archive case sourcessnap 9fs sources - mount -n /srv/sources /n/sourcessnap main/snapshot + mount -nC /srv/sources /n/sourcessnap main/snapshot # arbitrary venti archives case vac:* vacfs <{echo $1} diff --git a/sys/src/9/port/chan.c b/sys/src/9/port/chan.c index f1b1c3c8b..6c86aff03 100644 --- a/sys/src/9/port/chan.c +++ b/sys/src/9/port/chan.c @@ -469,23 +469,6 @@ chanfree(Chan *c) unlock(&chanalloc); } -void -cclose(Chan *c) -{ - if(c == nil || c->ref < 1 || c->flag&CFREE) - panic("cclose %#p", getcallerpc(&c)); - - DBG("cclose %p name=%s ref=%ld\n", c, chanpath(c), c->ref); - if(decref(c)) - return; - - if(!waserror()){ - devtab[c->type]->close(c); - poperror(); - } - chanfree(c); -} - /* * Queue a chan to be closed by one of the clunk procs. */ @@ -498,32 +481,6 @@ struct { QLock q; Rendez r; } clunkq; -void closeproc(void*); - -void -ccloseq(Chan *c) -{ - if(c == nil || c->ref < 1 || c->flag&CFREE) - panic("ccloseq %#p", getcallerpc(&c)); - - DBG("ccloseq %p name=%s ref=%ld\n", c, chanpath(c), c->ref); - - if(decref(c)) - return; - - lock(&clunkq.l); - clunkq.nqueued++; - c->next = nil; - if(clunkq.head) - clunkq.tail->next = c; - else - clunkq.head = c; - clunkq.tail = c; - unlock(&clunkq.l); - - if(!wakeup(&clunkq.r)) - kproc("closeproc", closeproc, nil); -} static int clunkwork(void*) @@ -531,25 +488,25 @@ clunkwork(void*) return clunkq.head != nil; } -void +static void closeproc(void*) { Chan *c; for(;;){ - qlock(&clunkq.q); if(clunkq.head == nil){ if(!waserror()){ tsleep(&clunkq.r, clunkwork, nil, 5000); poperror(); } - if(clunkq.head == nil){ - qunlock(&clunkq.q); - pexit("no work", 1); - } } lock(&clunkq.l); c = clunkq.head; + if(c == nil){ + unlock(&clunkq.l); + qunlock(&clunkq.q); + pexit("no work", 1); + } clunkq.head = c->next; clunkq.nclosed++; unlock(&clunkq.l); @@ -559,9 +516,61 @@ closeproc(void*) poperror(); } chanfree(c); + qlock(&clunkq.q); } } +static void +closechan(Chan *c, int sync) +{ + if(c == nil || c->ref < 1 || c->flag&CFREE) + panic("closechan %#p", getcallerpc(&c)); + + DBG("closechan %p name=%s ref=%ld\n", c, chanpath(c), c->ref); + + if(decref(c)) + return; + + if((c->flag&(CRCLOSE|CCACHE)) == CCACHE) + if((c->qid.type&(QTEXCL|QTMOUNT|QTAUTH)) == 0) + sync = 0; + + if(sync){ + if(!waserror()){ + devtab[c->type]->close(c); + poperror(); + } + chanfree(c); + } else { + lock(&clunkq.l); + clunkq.nqueued++; + c->next = nil; + if(clunkq.head) + clunkq.tail->next = c; + else + clunkq.head = c; + clunkq.tail = c; + unlock(&clunkq.l); + + if(canqlock(&clunkq.q)) + kproc("closeproc", closeproc, nil); + else + wakeup(&clunkq.r); + } +} + +void +cclose(Chan *c) +{ + closechan(c, 1); +} + +void +ccloseq(Chan *c) +{ + closechan(c, 0); +} + /* * Make sure we have the only copy of c. (Copy on write.) */ diff --git a/sys/src/9/port/sysfile.c b/sys/src/9/port/sysfile.c index 85fee6772..b810a4256 100644 --- a/sys/src/9/port/sysfile.c +++ b/sys/src/9/port/sysfile.c @@ -806,7 +806,7 @@ sseek(ulong *arg) cclose(c); nexterror(); } - if(devtab[c->type]->dc == '|') + if(devtab[c->type]->dc == L'|') error(Eisstream); off = 0;