ref: 48edf79c691d40e7310b105a1488282a9919f608
parent: 201fe8de4bd2597cee9ef94273abce2ddf0a1a58
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Jul 17 11:07:11 EDT 2024
gefs: modifying a directory should update qid.vers
--- a/sys/src/cmd/gefs/dat.h
+++ b/sys/src/cmd/gefs/dat.h
@@ -676,6 +676,7 @@
Mount *mnt;
Scan *scan; /* in progres scan */
Dent *dent; /* (pqid, name) ref, modified on rename */
+ Dent *dir;
Amsg *rclose;
void *auth;
@@ -692,6 +693,7 @@
int dmode;
char permit;
+ char fromdump;
};
enum {
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -36,6 +36,19 @@
}
static void
+touch(Dent *de, Msg *msg)
+{
+ wlock(de);
+ de->qid.vers++;
+ msg->op = Owstat;
+ msg->k = de->k;
+ msg->nk = de->nk;
+ msg->v = "\0";
+ msg->nv = 1;
+ wunlock(de);
+}
+
+static void
wrbarrier(void)
{
tracev("barrier", fs->qgen);
@@ -720,6 +733,7 @@
if(adec(&f->ref) != 0)
return;
clunkdent(f->mnt, f->dent);
+ clunkdent(f->mnt, f->dir);
clunkmount(f->mnt);
free(f);
}
@@ -758,6 +772,7 @@
if(n->mnt != nil)
ainc(&n->mnt->ref);
ainc(&n->dent->ref);
+ ainc(&n->dir->ref);
setmalloctag(n, getcallerpc(&c));
return n;
}
@@ -989,6 +1004,7 @@
f.mode = -1;
f.iounit = m->conn->iounit;
f.dent = de;
+ f.dir = de;
f.uid = -1;
f.duid = -1;
f.dgid = -1;
@@ -1167,6 +1183,7 @@
f.mode = -1;
f.iounit = m->conn->iounit;
f.dent = de;
+ f.dir = de;
f.uid = uid;
f.duid = d.uid;
f.dgid = d.gid;
@@ -1176,6 +1193,8 @@
error(Eperm);
f.permit = 1;
}
+ if(strcmp(aname, "dump") == 0)
+ f.fromdump = 1;
if(dupfid(m->conn, m->fid, &f) == nil)
error(Efid);
@@ -1190,29 +1209,39 @@
}
static int
-findparent(Tree *t, Fid *f, vlong *qpath, char **name, char *buf, int nbuf)
+findparent(Tree *t, vlong up, vlong *qpath, char **name, char *buf, int nbuf)
{
char *p, kbuf[Keymax];
Kvp kv;
Key k;
- p = packsuper(kbuf, sizeof(kbuf), f->pqpath);
+ p = packsuper(kbuf, sizeof(kbuf), up);
k.k = kbuf;
k.nk = p - kbuf;
if(!btlookup(t, &k, &kv, buf, nbuf))
- return 0;
+ error(Esrch);
*name = unpackdkey(kv.v, kv.nv, qpath);
return 1;
}
static void
+dkey(Key *k, vlong up, char *name, char *buf, int nbuf)
+{
+ char *p;
+
+ p = packdkey(buf, nbuf, up, name);
+ k->k = buf;
+ k->nk = p - buf;
+}
+
+static void
fswalk(Fmsg *m)
{
- char *p, *name, kbuf[Maxent], kvbuf[Kvmax];
+ char *name, kbuf[Maxent], kvbuf[Kvmax];
int duid, dgid, dmode;
- vlong up, prev;
+ vlong up, upup, prev;
+ Dent *dent, *dir;
Fid *o, *f;
- Dent *dent;
Mount *mnt;
Amsg *ao;
Tree *t;
@@ -1235,7 +1264,7 @@
error(Einuse);
t = o->mnt->root;
mnt = o->mnt;
- up = o->qpath;
+ up = o->pqpath;
prev = o->qpath;
rlock(o->dent);
d = *o->dent;
@@ -1250,41 +1279,30 @@
error(Elength);
if(fsaccess(o, d.mode, d.uid, d.gid, DMEXEC) != 0)
break;
- if(d.qid.path == Qdump){
- if((mnt = getmount(m->wname[i])) == nil)
- error(Esrch);
- if(waserror()){
- clunkmount(mnt);
- nexterror();
+ if(strcmp(name, "..") == 0){
+ if(up == -1 && o->fromdump){
+ mnt = fs->snapmnt;
+ filldumpdir(&d);
+ prev = -1ULL;
+ up = -1ULL;
+ r.wqid[i] = d.qid;
+ continue;
}
+ findparent(t, up, &prev, &name, kbuf, sizeof(kbuf));
+ }else if(d.qid.path == Qdump){
+ mnt = getmount(m->wname[i]);
+ name = "";
+ prev = -1ULL;
t = mnt->root;
- p = packdkey(kbuf, sizeof(kbuf), -1ULL, "");
- poperror();
- }else{
- if(strcmp(m->wname[i], "..") == 0){
- if(o->pqpath == Qdump){
- mnt = fs->snapmnt;
- filldumpdir(&d);
- duid = d.uid;
- dgid = d.gid;
- dmode = d.mode;
- goto Found;
- }
- if(!findparent(t, o, &prev, &name, kbuf, sizeof(kbuf)))
- error(Esrch);
- }
- p = packdkey(kbuf, sizeof(kbuf), prev, name);
}
+ up = prev;
duid = d.uid;
dgid = d.gid;
dmode = d.mode;
- k.k = kbuf;
- k.nk = p - kbuf;
+ dkey(&k, prev, name, kbuf, sizeof(kbuf));
if(!btlookup(t, &k, &kv, kvbuf, sizeof(kvbuf)))
break;
kv2dir(&kv, &d);
-Found:
- up = prev;
prev = d.qid.path;
r.wqid[i] = d.qid;
}
@@ -1299,6 +1317,7 @@
}
if(i > 0 && i == m->nwname){
lock(f);
+ ao = nil;
if(waserror()){
if(f != o)
clunkfid(m->conn, f, &ao);
@@ -1306,11 +1325,21 @@
unlock(f);
nexterror();
}
- if(up == Qdump)
- dent = getdent(mnt, -1ULL, &d);
- else
+ if(up == -1ULL){
+ /* the root contains itself, I guess */
dent = getdent(mnt, up, &d);
+ dir = getdent(mnt, up, &d);
+ }else{
+ dent = getdent(mnt, up, &d);
+ findparent(t, up, &upup, &name, kbuf, sizeof(kbuf));
+ dkey(&k, upup, name, kbuf, sizeof(kbuf));
+ if(!btlookup(t, &k, &kv, kvbuf, sizeof(kvbuf)))
+ error(Efs);
+ kv2dir(&kv, &d);
+ dir = getdent(mnt, upup, &d);
+ }
clunkdent(f->mnt, f->dent);
+ clunkdent(f->mnt, f->dir);
if(mnt != f->mnt){
clunkmount(f->mnt);
ainc(&mnt->ref);
@@ -1319,6 +1348,7 @@
f->qpath = r.wqid[i-1].path;
f->pqpath = up;
f->dent = dent;
+ f->dir = dir;
f->duid = duid;
f->dgid = dgid;
f->dmode = dmode;
@@ -1369,7 +1399,7 @@
Qid old;
Fcall r;
Dent *de;
- Msg mb[3];
+ Msg mb[4];
Xdir n;
Dir d;
Tree *t;
@@ -1552,6 +1582,7 @@
mb[nm].nv = mb[nm-1].nk;
nm++;
}
+ touch(f->dir, &mb[nm++]);
}else{
opbuf[0] = op;
mb[nm].op = Owstat;
@@ -1603,7 +1634,7 @@
vlong oldlen;
Qid old;
Fcall r;
- Msg mb[2];
+ Msg mb[3];
Fid *f;
Xdir d;
@@ -1688,6 +1719,7 @@
mb[nm].nv = p - upvbuf;
nm++;
}
+ touch(f->dent, &mb[nm++]);
upsert(f->mnt, mb, nm);
de = getdent(f->mnt, f->qpath, &d);
@@ -1739,7 +1771,8 @@
{
char *e, buf[Kvmax];
Fcall r;
- Msg mb[2];
+ int nm;
+ Msg mb[3];
Tree *t;
Kvp kv;
Fid *f;
@@ -1749,6 +1782,8 @@
return;
}
t = f->mnt->root;
+ nm = 0;
+ *ao = nil;
lock(f);
clunkfid(m->conn, f, ao);
/* rclose files are getting removed here anyways */
@@ -1758,7 +1793,6 @@
truncwait(f->dent, id);
wlock(f->dent);
- *ao = nil;
if(waserror()){
rerror(m, errmsg());
free(*ao);
@@ -1783,19 +1817,21 @@
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;
+ mb[nm].op = Odelete;
+ mb[nm].k = f->dent->k;
+ mb[nm].nk = f->dent->nk;
+ mb[nm].v = "\0";
+ mb[nm].nv = 1;
+ nm++;
unlock(f);
if(f->dent->qid.type & QTDIR){
packsuper(buf, sizeof(buf), f->qpath);
- mb[1].op = Oclobber;
- mb[1].k = buf;
- mb[1].nk = Upksz;
- mb[1].nv = 0;
- upsert(f->mnt, mb, 2);
+ mb[nm].op = Oclobber;
+ mb[nm].k = buf;
+ mb[nm].nk = Upksz;
+ mb[nm].nv = 0;
+ nm++;
}else{
if(*ao == nil)
*ao = emalloc(sizeof(Amsg), 1);
@@ -1806,8 +1842,9 @@
(*ao)->off = 0;
(*ao)->end = f->dent->length;
(*ao)->dent = nil;
- upsert(f->mnt, mb, 1);
}
+ touch(f->dir, &mb[nm++]);
+ upsert(f->mnt, mb, nm);
f->dent->gone = 1;
r.type = Rremove;
respond(m, &r);
--
⑨