async clunk for cached mounts, fix closeproc explosion
This commit is contained in:
parent
0c0b874d49
commit
6bd82b34fd
3 changed files with 62 additions and 53 deletions
|
@ -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}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue