shithub: gefs

Download patch

ref: b659452249216050f1d2f7f85d3b04220204a293
parent: 59b4c415b1a878a7c7f8a7725584489fca70cc61
author: Ori Bernstein <ori@eigenstate.org>
date: Sun May 12 20:03:21 EDT 2024

fs: clean up fids on lost connection

--- a/fs.c
+++ b/fs.c
@@ -8,6 +8,10 @@
 #include "fns.h"
 #include "atomic.h"
 
+static void	respond(Fmsg*, Fcall*);
+static void	rerror(Fmsg*, char*, ...);
+static void	clunkfid(Conn*, Fid*, Amsg**);
+
 int
 walk1(Tree *t, vlong up, char *name, Qid *qid, vlong *len)
 {
@@ -324,13 +328,33 @@
 {
 	char buf[ERRMAX];
 	va_list ap;
+	Amsg *a;
+	Fid *f;
+	int i;
 
 	va_start(ap, fmt);
 	vsnprint(buf, sizeof(buf), fmt, ap);
 	va_end(ap);
-	fprint(2, "%s\n", buf);
+	fprint(2, "hangup: %s\n", buf);
 	close(c->rfd);
 	close(c->wfd);
+	for(i = 0; i < Nfidtab; i++){
+		lock(&c->fidtablk[i]);
+		for(f = c->fidtab[i]; f != nil; f = f->next){
+			lock(f);
+			if(waserror()){
+				unlock(f);
+				continue;
+			}
+			a = nil;
+			clunkfid(c, f, &a);
+			unlock(f);
+			if(a != nil)
+				chsend(fs->admchan, a);
+			nexterror();
+		}
+		unlock(&c->fidtablk[i]);
+	}
 }
 
 static void
@@ -731,7 +755,7 @@
 }
 
 static void
-clunkfid(Conn *c, Fid *fid)
+clunkfid(Conn *c, Fid *fid, Amsg **ao)
 {
 	Fid *f, **pf;
 	u32int h;
@@ -748,6 +772,27 @@
 		pf = &f->next;
 	}
 	assert(f != nil);
+	if(f->scan != nil){
+		free(f->scan);
+		f->scan = nil;
+	}
+	if(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;
+		(*ao)->mnt = f->mnt;
+		(*ao)->qpath = f->qpath;
+		(*ao)->off = 0;
+		(*ao)->end = f->dent->length;
+		(*ao)->dent = f->dent;
+	}
 	unlock(&c->fidtablk[h]);
 }
 
@@ -1242,7 +1287,7 @@
 		lock(f);
 		if(waserror()){
 			if(f != o)
-				clunkfid(m->conn, f);
+				clunkfid(m->conn, f, nil);
 			unlock(f);
 			nexterror();
 		}
@@ -1521,28 +1566,7 @@
 		return;
 	}
 	lock(f);
-	if(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;
-		(*ao)->mnt = f->mnt;
-		(*ao)->qpath = f->qpath;
-		(*ao)->off = 0;
-		(*ao)->end = f->dent->length;
-		(*ao)->dent = f->dent;
-	}
-	if(f->scan != nil){
-		free(f->scan);
-		f->scan = nil;
-	}
-	clunkfid(m->conn, f);
+	clunkfid(m->conn, f, ao);
 	unlock(f);
 	r.type = Rclunk;
 	respond(m, &r);
@@ -1699,7 +1723,7 @@
 		return;
 	}
 	t = f->mnt->root;
-	clunkfid(m->conn, f);
+	clunkfid(m->conn, f, nil);
 
 	truncwait(f->dent, id);
 	wlock(f->dent);
@@ -2269,7 +2293,7 @@
 					rerror(m, Enofid);
 					continue;
 				}
-				clunkfid(m->conn, f);
+				clunkfid(m->conn, f, nil);
 				putfid(f);
 			}
 			rerror(m, Erdonly);