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