ref: 9e424a38e935655dc2c755056afb54e2840c0855
parent: 2a05dca22fba164e7549e359771aa26d88a7018a
author: Ori Bernstein <[email protected]>
date: Sun May 12 19:02:00 EDT 2024
fs: implement ORCLOSE
--- a/dat.h
+++ b/dat.h
@@ -320,6 +320,7 @@
AOsnap,
AOsync,
AOclear,
+ AOrclose,
};
struct Bptr {
@@ -392,7 +393,7 @@
struct { /* AOsync */
int halt;
};
- struct { /* AOclear */
+ struct { /* AOclear, AOrclose */
Mount *mnt;
Dent *dent;
vlong qpath;
@@ -683,6 +684,7 @@
int dmode;
char permit;
+ char rclose;
};
enum {
--- a/fs.c
+++ b/fs.c
@@ -1511,7 +1511,7 @@
static void
-fsclunk(Fmsg *m)
+fsclunk(Fmsg *m, Amsg **ao)
{
Fcall r;
Fid *f;
@@ -1521,6 +1521,23 @@
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;
@@ -1632,6 +1649,8 @@
f->pqpath = f->qpath;
f->qpath = d.qid.path;
f->dent = de;
+ if(m->mode & ORCLOSE)
+ f->rclose = 1;
r.type = Rcreate;
r.qid = d.qid;
@@ -1744,7 +1763,7 @@
static void
fsopen(Fmsg *m, int id, Amsg **ao)
{
- char *p, buf[Kvmax];
+ char *p, *e, buf[Kvmax];
int mbits;
Tree *t;
Fcall r;
@@ -1783,6 +1802,9 @@
if(f->dent->qid.type & QTEXCL)
if(f->dent->ref != 1)
error(Elocked);
+ if(m->mode & ORCLOSE)
+ if((e = candelete(f)) != nil)
+ error(e);
if(fsaccess(f, d.mode, d.uid, d.gid, mbits) == -1)
error(Eperm);
f->dent->length = d.length;
@@ -1797,7 +1819,6 @@
unlock(f);
error(Einuse);
}
- f->mode = mode2bits(m->mode);
if(m->mode & OTRUNC){
wlock(f->dent);
@@ -1838,6 +1859,9 @@
wunlock(f->dent);
poperror();
}
+ f->mode = mode2bits(m->mode);
+ if(m->mode & ORCLOSE)
+ f->rclose = 1;
unlock(f);
poperror();
respond(m, &r);
@@ -2149,6 +2173,7 @@
{
char err[128];
RWLock *lk;
+ Amsg *a;
Conn *c;
Fcall r;
Fmsg *m;
@@ -2180,13 +2205,14 @@
rlock(lk);
}
+ a = nil;
h = ihash(m->fid) % fs->nreaders;
switch(m->type){
/* sync setup, must not access tree */
case Tversion: fsversion(m); break;
case Tauth: fsauth(m); break;
- case Tclunk: fsclunk(m); break;
case Tflush: fsflush(m); break;
+ case Tclunk: fsclunk(m, &a); break;
/* mutators */
case Tcreate: chsend(fs->wrchan, m); break;
@@ -2202,7 +2228,7 @@
/* both */
case Topen:
- if((m->mode & OTRUNC) || (m->mode & 0xf) == OEXEC)
+ if((m->mode & OTRUNC) || (m->mode & ORCLOSE) != 0)
chsend(fs->wrchan, m);
else
chsend(fs->rdchan[h], m);
@@ -2217,6 +2243,8 @@
break;
}
assert(estacksz() == 0);
+ if(a != nil)
+ chsend(fs->admchan, a);
}
}
@@ -2349,7 +2377,7 @@
void
runsweep(int id, void*)
{
- char buf[Offksz];
+ char buf[Kvmax];
Bptr bp, nb, *oldhd;
vlong off;
Tree *t;
@@ -2356,8 +2384,8 @@
Arena *a;
Amsg *am;
Blk *b;
- Msg m;
- int i;
+ Msg m, mb[2];
+ int i, nm;
if((oldhd = calloc(fs->narena, sizeof(Bptr))) == nil)
sysfatal("malloc log heads");
@@ -2459,6 +2487,23 @@
poperror();
break;
+ case AOrclose:
+ nm = 0;
+ mb[nm].op = Odelete;
+ mb[nm].k = am->dent->k;
+ mb[nm].nk = am->dent->nk;
+ mb[nm].nv = 0;
+ nm++;
+ if(am->dent->qid.type & QTDIR){
+ packsuper(buf, sizeof(buf), am->qpath);
+ mb[nm].op = Oclobber;
+ mb[nm].k = buf;
+ mb[nm].nk = Upksz;
+ mb[nm].nv = 0;
+ nm++;
+ }
+ upsert(am->mnt, mb, nm);
+ /* fallthrough */
case AOclear:
tracem("bgclear");
if(waserror()){