shithub: riscv

Download patch

ref: 1281b234e893b2306dbfef442144b75873f2365c
parent: 9c40e15ba8ae000f73c23d89143d6c44b75220fd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Feb 20 20:02:32 EST 2014

exportfs: reverting previous changes

getting strange tag mismatches on some machines. needs
to be debugged. until then, reverting the change.

--- a/sys/src/cmd/exportfs/exportfs.c
+++ b/sys/src/cmd/exportfs/exportfs.c
@@ -460,8 +460,8 @@
 		fatal(Enomem);
 	n = convS2M(t, data, messagesize);
 	if(write(netfd, data, n)!=n){
-		/* not fatal, might have got a note due to flush */
-		fprint(2, "exportfs: short write in reply: %r\n");
+		syslog(0, "exportfs", "short write: %r");
+		fatal("mount write");
 	}
 	free(data);
 }
@@ -570,6 +570,8 @@
 		unlock(&sbufalloc);
 		w = emallocz(sizeof(*w) + messagesize);
 	}
+	w->pid = 0;
+	w->canint = 0;
 	w->flushtag = NOTAG;
 	return w;
 }
@@ -577,6 +579,8 @@
 void
 putsbuf(Fsrpc *w)
 {
+	w->pid = 0;
+	w->canint = 0;
 	w->flushtag = NOTAG;
 	lock(&sbufalloc);
 	w->next = sbufalloc.free;
--- a/sys/src/cmd/exportfs/exportfs.h
+++ b/sys/src/cmd/exportfs/exportfs.h
@@ -15,6 +15,8 @@
 struct Fsrpc
 {
 	Fsrpc	*next;		/* freelist */
+	uintptr	pid;		/* Pid of slave process executing the rpc */
+	int	canint;		/* Interrupt gate */
 	int	flushtag;	/* Tag on which to reply to flush */
 	Fcall	work;		/* Plan 9 incoming Fcall */
 	uchar	buf[];		/* Data buffer */
@@ -51,10 +53,9 @@
 
 struct Proc
 {
-	Lock;
+	uintptr	pid;
 	Fsrpc	*busy;
 	Proc	*next;
-	int	pid;
 };
 
 struct Qidtab
@@ -69,6 +70,7 @@
 
 enum
 {
+	MAXPROC		= 50,
 	FHASHSIZE	= 64,
 	Fidchunk	= 1000,
 	Npsmpt		= 32,
@@ -126,7 +128,7 @@
 void	slaveopen(Fsrpc*);
 void	slaveread(Fsrpc*);
 void	slavewrite(Fsrpc*);
-void	blockingslave(Proc*);
+void	blockingslave(void);
 void	reopen(Fid *f);
 void	noteproc(int, char*);
 void	flushaction(void*, char*);
--- a/sys/src/cmd/exportfs/exportsrv.c
+++ b/sys/src/cmd/exportfs/exportsrv.c
@@ -64,20 +64,14 @@
 
 	for(m = Proclist; m; m = m->next){
 		w = m->busy;
-		if(w == nil || w->work.tag != t->work.oldtag)
-			continue;
-
-		lock(m);
-		w = m->busy;
-		if(w != nil && w->work.tag == t->work.oldtag) {
+		if(w != 0 && w->pid == m->pid && w->work.tag == t->work.oldtag) {
 			w->flushtag = t->work.tag;
 			DEBUG(DFD, "\tset flushtag %d\n", t->work.tag);
-			postnote(PNPROC, m->pid, "flush");
-			unlock(m);
+			if(w->canint)
+				postnote(PNPROC, w->pid, "flush");
 			putsbuf(t);
 			return;
 		}
-		unlock(m);
 	}
 
 	reply(&t->work, &rhdr, 0);
@@ -465,10 +459,10 @@
 void
 slave(Fsrpc *f)
 {
-	static int nproc;
-	Proc *p, **l;
+	Proc *p;
+	uintptr pid;
 	Fcall rhdr;
-	int pid;
+	static int nproc;
 
 	if(readonly){
 		switch(f->work.type){
@@ -485,41 +479,30 @@
 		}
 	}
 	for(;;) {
-		for(l = &Proclist; (p = *l) != nil; l = &p->next) {
-			if(p->busy != nil)
-				continue;
-
-			p->busy = f;
-			while(rendezvous(p, f) == (void*)~0)
-				;
-
-			/* swept a slave proc */
-			if(f == nil){
-				*l = p->next;
-				free(p);
-				nproc--;
-				break;
-			}
-			f = nil;
-
-			/*
-			 * as long as the number of slave procs
-			 * is small, dont bother sweeping.
-			 */
-			if(nproc < 16)
-				break;
+		for(p = Proclist; p; p = p->next) {
+			if(p->busy == 0) {
+				f->pid = p->pid;
+				p->busy = f;
+				do {
+					pid = (uintptr)rendezvous((void*)p->pid, f);
+				}
+				while(pid == ~0);	/* Interrupted */
+				if(pid != p->pid)
+					fatal("rendezvous sync fail");
+				return;
+			}	
 		}
-		if(f == nil)
-			return;
 
-		p = emallocz(sizeof(Proc));
-		pid = rfork(RFPROC|RFMEM|RFNOWAIT);
-		switch(pid) {
-		case -1:
+		if(nproc >= MAXPROC){
 			reply(&f->work, &rhdr, Enoprocs);
 			putsbuf(f);
-			free(p);
 			return;
+		}
+		nproc++;
+		pid = rfork(RFPROC|RFMEM);
+		switch(pid) {
+		case -1:
+			fatal("rfork");
 
 		case 0:
 			if (local[0] != '\0')
@@ -528,34 +511,44 @@
 						local, remote);
 				else
 					procsetname("%s -> %s", local, remote);
-			blockingslave(p);
-			_exits(0);
+			blockingslave();
+			fatal("slave");
 
 		default:
+			p = emallocz(sizeof(Proc));
+			p->busy = 0;
 			p->pid = pid;
 			p->next = Proclist;
 			Proclist = p;
-			nproc++;
+			while(rendezvous((void*)pid, p) == (void*)~0)
+				;
 		}
 	}
 }
 
 void
-blockingslave(Proc *m)
+blockingslave(void)
 {
 	Fsrpc *p;
 	Fcall rhdr;
+	Proc *m;
+	uintptr pid;
 
 	notify(flushaction);
 
+	pid = getpid();
+
+	do {
+		m = rendezvous((void*)pid, 0);
+	}
+	while(m == (void*)~0);	/* Interrupted */
+	
 	for(;;) {
-		p = rendezvous(m, nil);
-		if(p == (void*)~0)	/* Interrupted */
+		p = rendezvous((void*)pid, (void*)pid);
+		if(p == (void*)~0)			/* Interrupted */
 			continue;
-		if(p == nil)		/* Swept */
-			break;
 
-		DEBUG(DFD, "\tslave: %d %F\n", m->pid, &p->work);
+		DEBUG(DFD, "\tslave: %p %F p %p\n", pid, &p->work, p->pid);
 		if(p->flushtag != NOTAG)
 			goto flushme;
 
@@ -575,17 +568,13 @@
 		default:
 			reply(&p->work, &rhdr, "exportfs: slave type error");
 		}
-flushme:
-		lock(m);
-		m->busy = nil;
-		unlock(m);
-
-		/* no more flushes can come in now */
 		if(p->flushtag != NOTAG) {
+flushme:
 			p->work.type = Tflush;
 			p->work.tag = p->flushtag;
 			reply(&p->work, &rhdr, 0);
 		}
+		m->busy = 0;
 		putsbuf(p);
 	}
 }
@@ -665,8 +654,16 @@
 	
 	path = makepath(f->f, "");
 	DEBUG(DFD, "\topen: %s %d\n", path, work->mode);
+
+	p->canint = 1;
+	if(p->flushtag != NOTAG){
+		free(path);
+		return;
+	}
+	/* There is a race here I ignore because there are no locks */
 	f->fid = open(path, work->mode);
 	free(path);
+	p->canint = 0;
 	if(f->fid < 0 || (d = dirfstat(f->fid)) == nil) {
 	Error:
 		errstr(err, sizeof err);
@@ -706,6 +703,9 @@
 	}
 
 	n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
+	p->canint = 1;
+	if(p->flushtag != NOTAG)
+		return;
 	data = malloc(n);
 	if(data == 0) {
 		reply(work, &rhdr, Enomem);
@@ -717,6 +717,7 @@
 		r = preaddir(f, (uchar*)data, n, work->offset);
 	else
 		r = pread(f->fid, data, n, work->offset);
+	p->canint = 0;
 	if(r < 0) {
 		free(data);
 		errstr(err, sizeof err);
@@ -723,6 +724,7 @@
 		reply(work, &rhdr, err);
 		return;
 	}
+
 	DEBUG(DFD, "\tread: fd=%d %d bytes\n", f->fid, r);
 
 	rhdr.data = data;
@@ -748,7 +750,11 @@
 	}
 
 	n = (work->count > messagesize-IOHDRSZ) ? messagesize-IOHDRSZ : work->count;
+	p->canint = 1;
+	if(p->flushtag != NOTAG)
+		return;
 	n = pwrite(f->fid, work->data, n, work->offset);
+	p->canint = 0;
 	if(n < 0) {
 		errstr(err, sizeof err);
 		reply(work, &rhdr, err);