shithub: patch

Download patch

ref: f6f3e05cf56fab3261d49b0bb26f2dbdd0aa7188
parent: d5db06b9b782a4e90aece9e8318f64fc0a61cdf4
author: qwx <qwx@sciops.net>
date: Mon Nov 3 04:06:58 EST 2025

add unionfs-norace: fix crashes due to race conditions

fixing these race conditions while retaining the srvacq/release model
is too difficult, this needs a redesign instead. in practice, for my
purposes performance is good enough even without these.

--- /dev/null
+++ b/unionfs-norace
@@ -1,0 +1,159 @@
+diff c29f9884bb2aba8ac6a2b9286d582ba86dd61ae1 uncommitted
+--- a/unionfs.c
++++ b/unionfs.c
+@@ -198,7 +198,7 @@
+ 
+ 	f->pid = getpid();
+ 	atnotify(catchflush, 1);
+-	srvrelease(&thefs);
++//	srvrelease(&thefs);
+ 	if(f->mode & DMDIR){
+ 		f->mtpt = mtptgrab();
+ 		path = s_new();
+@@ -222,13 +222,13 @@
+ 	R->iounit = iounit(f->fd);
+ 	if(f->flushed == 0)
+ 		respond(r, nil);
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
+ 	atnotify(catchflush, 0);
+ 	return;
+ error:
+ 	if(f->flushed == 0)
+ 		responderror(r);
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
+ 	atnotify(catchflush, 0);
+ }
+ 
+@@ -238,7 +238,7 @@
+ 	FILE *f;
+ 	
+ 	f = r->fid->aux;
+-	srvrelease(&thefs);
++//	srvrelease(&thefs);
+ 	if(remove(s_to_c(f->realpath)) == -1){
+ 		responderror(r);
+ 		goto done;
+@@ -245,7 +245,8 @@
+ 	}
+ 	respond(r, nil);
+ done:
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
++	;
+ }
+ 
+ int
+@@ -275,15 +276,19 @@
+ 
+ 	f->pid = getpid();
+ 	atnotify(catchflush, 1);
+-	srvrelease(&thefs);
++//	srvrelease(&thefs);
+ 	if(f->mode&DMDIR){
+ 		if(T->offset == 0){
+-			if(seek(f->fd, 0, 0) == -1)
++			if(seek(f->fd, 0, 0) == -1){
++				fprint(2, "fsread: seek %r\n");
+ 				goto error;
++			}
+ 			if(f->dl != nil)
+ 				dirlistfree(f->dl);
+-			if((f->dl = dirlist(f->fd)) == nil)
++			if((f->dl = dirlist(f->fd)) == nil){
++				fprint(2, "fsread: dirlist %r\n");
+ 				goto error;
++			}
+ 		}
+ 		dirread9p(r, dirgen, f->dl);
+ 	}else{
+@@ -293,13 +298,13 @@
+ 	}
+ 	if(f->flushed == 0)
+ 		respond(r, nil);
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
+ 	atnotify(catchflush, 0);
+ 	return;
+ error:
+ 	if(f->flushed == 0)
+ 		responderror(r);
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
+ 	atnotify(catchflush, 0);
+ }
+ 
+@@ -313,7 +318,7 @@
+ 	R = &r->ofcall;
+ 	f = r->fid->aux;
+ 	
+-	srvrelease(&thefs);
++//	srvrelease(&thefs);
+ 	atnotify(catchflush, 1);
+ 	if((R->count = pwrite(f->fd, T->data, T->count, T->offset)) != T->count){
+ 		if(f->flushed == 0)
+@@ -323,7 +328,7 @@
+ 	if(f->flushed == 0)
+ 		respond(r, nil);
+ done:
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
+ 	atnotify(catchflush, 0);
+ }
+ 
+@@ -396,7 +401,7 @@
+ 	R = &r->ofcall;
+ 	parent = r->fid->aux;
+ 	
+-	srvrelease(&thefs);
++//	srvrelease(&thefs);
+ 	for(i = 0; i < nbranch; i++)
+ 		if(branch[i].create == 1)
+ 			break;
+@@ -409,7 +414,7 @@
+ 		if(fd != -1)
+ 			close(fd);
+ 		responderror(r);
+-		srvacquire(&thefs);
++	//	srvacquire(&thefs);
+ 		return;
+ 	}
+ 	walk(realpath, T->name, nil);
+@@ -429,7 +434,7 @@
+ 	r->fid->aux = f;
+ 	R->qid = f->qid;
+ 	respond(r, nil);
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
+ }
+ 
+ void
+@@ -436,7 +441,7 @@
+ fsstat(Req *r)
+ {
+ 	FILE *f = r->fid->aux;
+-	
++
+ 	dircopy(&r->d, f);
+ 	respond(r, nil);
+ }
+@@ -446,7 +451,7 @@
+ {
+ 	FILE *f = r->fid->aux;
+ 	
+-	srvrelease(&thefs);
++//	srvrelease(&thefs);
+ 	if(dirwstat(s_to_c(f->realpath), &r->d) == -1){
+ 		responderror(r);
+ 		goto done;
+@@ -453,7 +458,8 @@
+ 	}
+ 	respond(r, nil);
+ done:
+-	srvacquire(&thefs);
++//	srvacquire(&thefs);
++	;
+ }
+ 
+ char*
--