ref: 79323e05d14bc7d2672edac45aae88e494c06eaa
parent: 04d0d77e4b8a5525a86e7d84e0620001a099324f
author: Ori Bernstein <ori@eigenstate.org>
date: Wed May 29 13:12:21 EDT 2024
gefs: make dent cache per-mount with a global dent cache, directory entries from different trees can be cached. This almost works, but QID state can change as the files get modified -- ownership, permissions, and similar can get changed. A global mount cache means that changes to a qid may leak across mount boundaries. Don't do that.
--- a/sys/src/cmd/gefs/dat.h
+++ b/sys/src/cmd/gefs/dat.h
@@ -545,10 +545,6 @@
User *users;
int nusers;
- /* open directory entries */
- Lock dtablk;
- Dent *dtab[Ndtab];
-
/* slow block io */
QLock blklk[32];
@@ -635,6 +631,10 @@
Tree *root; /* EBR protected */
int flag;
+
+ /* open directory entries */
+ Lock dtablk;
+ Dent *dtab[Ndtab];
/* snapshot history */
char minutely[60][128];
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -527,7 +527,7 @@
}
static Dent*
-getdent(vlong pqid, Xdir *d)
+getdent(Mount *mnt, vlong pqid, Xdir *d)
{
Dent *de;
char *e;
@@ -534,8 +534,8 @@
u32int h;
h = ihash(d->qid.path) % Ndtab;
- lock(&fs->dtablk);
- for(de = fs->dtab[h]; de != nil; de = de->next){
+ lock(&mnt->dtablk);
+ for(de = mnt->dtab[h]; de != nil; de = de->next){
if(de->qid.path == d->qid.path){
ainc(&de->ref);
goto Out;
@@ -558,11 +558,11 @@
de->k = de->buf;
de->nk = e - de->buf;
de->name = de->buf + 11;
- de->next = fs->dtab[h];
- fs->dtab[h] = de;
+ de->next = mnt->dtab[h];
+ mnt->dtab[h] = de;
Out:
- unlock(&fs->dtablk);
+ unlock(&mnt->dtablk);
return de;
}
@@ -674,7 +674,7 @@
}
static void
-clunkdent(Dent *de)
+clunkdent(Mount *mnt, Dent *de)
{
Dent *e, **pe;
u32int h;
@@ -685,12 +685,12 @@
free(de);
return;
}
- lock(&fs->dtablk);
+ lock(&mnt->dtablk);
if(adec(&de->ref) != 0)
goto Out;
h = ihash(de->qid.path) % Ndtab;
- pe = &fs->dtab[h];
- for(e = fs->dtab[h]; e != nil; e = e->next){
+ pe = &mnt->dtab[h];
+ for(e = mnt->dtab[h]; e != nil; e = e->next){
if(e == de)
break;
pe = &e->next;
@@ -699,7 +699,7 @@
*pe = e->next;
free(de);
Out:
- unlock(&fs->dtablk);
+ unlock(&mnt->dtablk);
}
static Fid*
@@ -724,8 +724,8 @@
{
if(adec(&f->ref) != 0)
return;
+ clunkdent(f->mnt, f->dent);
clunkmount(f->mnt);
- clunkdent(f->dent);
free(f);
}
@@ -1163,7 +1163,7 @@
error(Enosnap);
kv2dir(&kv, &d);
}
- de = getdent(-1, &d);
+ de = getdent(mnt, -1, &d);
memset(&f, 0, sizeof(Fid));
f.fid = NOFID;
f.mnt = mnt;
@@ -1190,7 +1190,7 @@
poperror();
-Err: clunkdent(de);
+Err: clunkdent(mnt, de);
clunkmount(mnt);
}
@@ -1312,15 +1312,15 @@
nexterror();
}
if(up == Qdump)
- dent = getdent(-1ULL, &d);
+ dent = getdent(mnt, -1ULL, &d);
else
- dent = getdent(up, &d);
+ dent = getdent(mnt, up, &d);
+ clunkdent(f->mnt, f->dent);
if(mnt != f->mnt){
clunkmount(f->mnt);
ainc(&mnt->ref);
f->mnt = mnt;
}
- clunkdent(f->dent);
f->qpath = r.wqid[i-1].path;
f->pqpath = up;
f->dent = dent;
@@ -1694,8 +1694,8 @@
}
upsert(f->mnt, mb, nm);
- de = getdent(f->qpath, &d);
- clunkdent(f->dent);
+ de = getdent(f->mnt, f->qpath, &d);
+ clunkdent(f->mnt, f->dent);
f->mode = mode2bits(m->mode);
f->pqpath = f->qpath;
f->qpath = d.qid.path;
@@ -2616,7 +2616,7 @@
am->dent->trunc = 0;
rwakeup(&am->dent->truncrz);
qunlock(&am->dent->trunclk);
- clunkdent(am->dent);
+ clunkdent(am->mnt, am->dent);
}
clunkmount(am->mnt);
poperror();