shithub: gefs

Download patch

ref: 856c1dd4e268797581995d9addc0aa3c939e100a
parent: a289e5c5a595ae8e3283c1b5a616fcc5068715a4
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Apr 27 23:12:49 EDT 2023

fs: handle deletion via different fids

phase errors are your friends.

--- a/dat.h
+++ b/dat.h
@@ -543,6 +543,7 @@
 	Xdir;
 	Dent	*next;
 	long	ref;
+	char	gone;
 
 	char	buf[Maxent];
 };
--- a/fs.c
+++ b/fs.c
@@ -1134,6 +1134,10 @@
 	}
 	de = f->dent;
 	wlock(de);
+	if(de->gone){
+		rerror(m, Ephase);
+		goto Out;
+	}
 	if((de->qid.type & QTAUTH) || (de->qid.path & Qdump)){
 		rerror(m, Emode);
 		goto Out;
@@ -1278,7 +1282,7 @@
 
 	/* update directory entry */
 	nm = 0;
-	if(rename){
+	if(rename && !de->gone){
 		mb[nm].op = Odelete;
 		mb[nm].Key = de->Key;
 		mb[nm].v = nil;
@@ -1451,6 +1455,7 @@
 	f->qpath = d.qid.path;
 	f->dent = de;
 	wlock(de);
+	de->gone = 0;
 	if((e = clearb(f, 0, de->length)) != nil){
 		unlock(f);
 		clunkdent(de);
@@ -1504,7 +1509,11 @@
 	}
 	clunkfid(m->conn, f);
 
-	rlock(f->dent);
+	wlock(f->dent);
+	if(f->dent->gone){
+		e = Ephase;
+		goto Error;
+	}
 	if((e = candelete(f)) != nil)
 		goto Error;
 	if(fsaccess(f, f->dmode, f->duid, f->dgid, DMWRITE) == -1){
@@ -1515,6 +1524,7 @@
 	mb.k = f->dent->k;
 	mb.nk = f->dent->nk;
 	mb.nv = 0;
+
 	if((e = upsert(f->mnt, &mb, 1)) != nil)
 		goto Error;
 	if(f->dent->qid.type == QTFILE){
@@ -1522,8 +1532,9 @@
 		if(e != nil)
 			goto Error;
 	}
+	f->dent->gone = 1;
+	wunlock(f->dent);
 
-	runlock(f->dent);
 	r.type = Rremove;
 	respond(m, &r);
 	putfid(f);
@@ -1530,7 +1541,7 @@
 	return;
 
 Error:
-	runlock(f->dent);
+	wunlock(f->dent);
 	rerror(m, e);
 	putfid(f);
 }
@@ -1566,12 +1577,19 @@
 			return;
 		}
 	}
+	wlock(f->dent);
+	if(f->dent->gone){
+		rerror(m, Ephase);
+		wunlock(f->dent);
+		putfid(f);
+		return;
+	}
 	if(fsaccess(f, d.mode, d.uid, d.gid, mbits) == -1){
 		rerror(m, Eperm);
+		wunlock(f->dent);
 		putfid(f);
 		return;
 	}
-	wlock(f->dent);
 	f->dent->length = d.length;
 	wunlock(f->dent);
 	r.type = Ropen;
@@ -1887,6 +1905,13 @@
 		putfid(f);
 		return;
 	}
+	wlock(f->dent);
+	if(f->dent->gone){
+		rerror(m, Ephase);
+		wunlock(f->dent);
+		putfid(f);
+		return;
+	}
 	if(f->dent->qid.type == QTAUTH){
 		e = writeauth(m, f, &r);
 		if(e != nil)
@@ -1893,11 +1918,11 @@
 			rerror(m, e);
 		else
 			respond(m, &r);
+		wunlock(f->dent);
 		putfid(f);
 		return;
 	}		
 
-	wlock(f->dent);
 	w = 0;
 	p = m->data;
 	o = m->offset;