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);
--
⑨