shithub: riscv

Download patch

ref: 037bc7b4328948994f8b8fa2be487aac1cca835f
parent: b2cd4959fe3695d317b6b75956da55a7f77ed858
author: Ori Bernstein <ori@eigenstate.org>
date: Sat May 18 14:28:17 EDT 2024

gefs: make it impossible for clunkfid to error

in out of memory situations, clunkfid could run
out of memory and error; preallocating moves the
error to fscreate/fsopen, which are prepared to
handle them.

--- a/sys/src/cmd/gefs/dat.h
+++ b/sys/src/cmd/gefs/dat.h
@@ -664,7 +664,8 @@
 	 */
 	Mount	*mnt;
 	Scan	*scan;	/* in progres scan */
-	Dent	*dent;	/* (pqid, name) ref, modified on rename */	
+	Dent	*dent;	/* (pqid, name) ref, modified on rename */
+	Amsg	*rclose;	
 	void	*auth;
 
 	u32int	fid;
@@ -680,7 +681,6 @@
 	int	dmode;
 
 	char	permit;
-	char	rclose;
 };
 
 enum {
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -773,14 +773,17 @@
 		free(f->scan);
 		f->scan = nil;
 	}
-	if(f->rclose){
+	if(f->rclose != nil){
+		*ao = f->rclose;
+
 		qlock(&f->dent->trunclk);
 		f->dent->trunc = 1;
 		qunlock(&f->dent->trunclk);
+
 		wlock(f->dent);
 		f->dent->gone = 1;
 		wunlock(f->dent);
-		*ao = emalloc(sizeof(Amsg), 1);
+
 		aincl(&f->dent->ref, 1);
 		aincl(&f->mnt->ref, 1);
 		(*ao)->op = AOrclose;
@@ -1200,6 +1203,7 @@
 	Fid *o, *f;
 	Dent *dent;
 	Mount *mnt;
+	Amsg *ao;
 	Tree *t;
 	Fcall r;
 	Xdir d;
@@ -1286,7 +1290,8 @@
 		lock(f);
 		if(waserror()){
 			if(f != o)
-				clunkfid(m->conn, f, nil);
+				clunkfid(m->conn, f, &ao);
+			assert(ao == nil);
 			unlock(f);
 			nexterror();
 		}
@@ -1679,7 +1684,7 @@
 	f->qpath = d.qid.path;
 	f->dent = de;
 	if(m->mode & ORCLOSE)
-		f->rclose = 1;
+		f->rclose = emalloc(sizeof(Amsg), 1);
 
 	r.type = Rcreate;
 	r.qid = d.qid;
@@ -1728,7 +1733,12 @@
 		return;
 	}
 	t = f->mnt->root;
-	clunkfid(m->conn, f, nil);
+	lock(f);
+	clunkfid(m->conn, f, ao);
+	/* rclose files are getting removed here anyways */
+	if(*ao != nil)
+		f->rclose = nil;
+	unlock(f);
 
 	truncwait(f->dent, id);
 	wlock(f->dent);
@@ -1756,10 +1766,12 @@
 		error(e);
 	if(fsaccess(f, f->dmode, f->duid, f->dgid, DMWRITE) == -1)
 		error(Eperm);
+	lock(f);
 	mb[0].op = Odelete;
 	mb[0].k = f->dent->k;
 	mb[0].nk = f->dent->nk;
 	mb[0].nv = 0;
+	unlock(f);
 
 	if(f->dent->qid.type & QTDIR){
 		packsuper(buf, sizeof(buf), f->qpath);
@@ -1769,7 +1781,8 @@
 		mb[1].nv = 0;
 		upsert(f->mnt, mb, 2);
 	}else{
-		*ao = emalloc(sizeof(Amsg), 1);
+		if(*ao == nil)
+			*ao = emalloc(sizeof(Amsg), 1);
 		aincl(&f->mnt->ref, 1);
 		(*ao)->op = AOclear;
 		(*ao)->mnt = f->mnt;
@@ -1890,7 +1903,7 @@
 	}
 	f->mode = mode2bits(m->mode);
 	if(m->mode & ORCLOSE)
-		f->rclose = 1;
+		f->rclose = emalloc(sizeof(Amsg), 1);
 	unlock(f);
 	poperror();
 	respond(m, &r);
@@ -2298,7 +2311,10 @@
 					rerror(m, Enofid);
 					continue;
 				}
-				clunkfid(m->conn, f, nil);
+				clunkfid(m->conn, f, &a);
+				/* read only: ignore rclose */
+				f->rclose = nil;
+				free(a);
 				putfid(f);
 			}
 			rerror(m, Erdonly);