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