shithub: riscv

Download patch

ref: 6bd82b34fd6ff8955ff372c1e84ec94e80ddf98a
parent: 0c0b874d49a51c09c1d2e97e9fdb9a480407d938
author: cinap_lenrek <[email protected]>
date: Fri Apr 27 13:51:20 EDT 2012

async clunk for cached mounts, fix closeproc explosion

--- a/rc/bin/9fs
+++ b/rc/bin/9fs
@@ -37,13 +37,13 @@
 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}
--- a/sys/src/9/port/chan.c
+++ b/sys/src/9/port/chan.c
@@ -469,23 +469,6 @@
 	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,33 +481,7 @@
 	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 @@
 	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,7 +516,59 @@
 			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);
 }
 
 /*
--- a/sys/src/9/port/sysfile.c
+++ b/sys/src/9/port/sysfile.c
@@ -806,7 +806,7 @@
 		cclose(c);
 		nexterror();
 	}
-	if(devtab[c->type]->dc == '|')
+	if(devtab[c->type]->dc == L'|')
 		error(Eisstream);
 
 	off = 0;