async clunk for cached mounts, fix closeproc explosion

This commit is contained in:
cinap_lenrek 2012-04-27 17:51:20 +02:00
parent 0c0b874d49
commit 6bd82b34fd
3 changed files with 62 additions and 53 deletions

View file

@ -37,13 +37,13 @@ case other
case juke # ye olde file server case juke # ye olde file server
srv -q il!jukefs && mount /srv/il!jukefs /n/juke srv -q il!jukefs && mount /srv/il!jukefs /n/juke
case sources 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 case sourcesdump
9fs sources 9fs sources
mount -n /srv/sources /n/sourcesdump main/archive mount -nC /srv/sources /n/sourcesdump main/archive
case sourcessnap case sourcessnap
9fs sources 9fs sources
mount -n /srv/sources /n/sourcessnap main/snapshot mount -nC /srv/sources /n/sourcessnap main/snapshot
# arbitrary venti archives # arbitrary venti archives
case vac:* case vac:*
vacfs <{echo $1} vacfs <{echo $1}

View file

@ -469,23 +469,6 @@ chanfree(Chan *c)
unlock(&chanalloc); 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. * Queue a chan to be closed by one of the clunk procs.
*/ */
@ -498,19 +481,67 @@ struct {
QLock q; QLock q;
Rendez r; Rendez r;
} clunkq; } clunkq;
void closeproc(void*);
void static int
ccloseq(Chan *c) clunkwork(void*)
{
return clunkq.head != nil;
}
static void
closeproc(void*)
{
Chan *c;
for(;;){
if(clunkq.head == nil){
if(!waserror()){
tsleep(&clunkq.r, clunkwork, nil, 5000);
poperror();
}
}
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);
qunlock(&clunkq.q);
if(!waserror()){
devtab[c->type]->close(c);
poperror();
}
chanfree(c);
qlock(&clunkq.q);
}
}
static void
closechan(Chan *c, int sync)
{ {
if(c == nil || c->ref < 1 || c->flag&CFREE) if(c == nil || c->ref < 1 || c->flag&CFREE)
panic("ccloseq %#p", getcallerpc(&c)); panic("closechan %#p", getcallerpc(&c));
DBG("ccloseq %p name=%s ref=%ld\n", c, chanpath(c), c->ref); DBG("closechan %p name=%s ref=%ld\n", c, chanpath(c), c->ref);
if(decref(c)) if(decref(c))
return; 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); lock(&clunkq.l);
clunkq.nqueued++; clunkq.nqueued++;
c->next = nil; c->next = nil;
@ -521,45 +552,23 @@ ccloseq(Chan *c)
clunkq.tail = c; clunkq.tail = c;
unlock(&clunkq.l); unlock(&clunkq.l);
if(!wakeup(&clunkq.r)) if(canqlock(&clunkq.q))
kproc("closeproc", closeproc, nil); kproc("closeproc", closeproc, nil);
} else
wakeup(&clunkq.r);
static int }
clunkwork(void*)
{
return clunkq.head != nil;
} }
void void
closeproc(void*) cclose(Chan *c)
{ {
Chan *c; closechan(c, 1);
}
for(;;){ void
qlock(&clunkq.q); ccloseq(Chan *c)
if(clunkq.head == nil){ {
if(!waserror()){ closechan(c, 0);
tsleep(&clunkq.r, clunkwork, nil, 5000);
poperror();
}
if(clunkq.head == nil){
qunlock(&clunkq.q);
pexit("no work", 1);
}
}
lock(&clunkq.l);
c = clunkq.head;
clunkq.head = c->next;
clunkq.nclosed++;
unlock(&clunkq.l);
qunlock(&clunkq.q);
if(!waserror()){
devtab[c->type]->close(c);
poperror();
}
chanfree(c);
}
} }
/* /*

View file

@ -806,7 +806,7 @@ sseek(ulong *arg)
cclose(c); cclose(c);
nexterror(); nexterror();
} }
if(devtab[c->type]->dc == '|') if(devtab[c->type]->dc == L'|')
error(Eisstream); error(Eisstream);
off = 0; off = 0;