ref: 3ee102676b5d02a2310ba38b8565e96ee4df6aa9
parent: 0a951c125346c524c02bbe03b9541ced9464046f
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Nov 4 23:16:43 EST 2023
snap: don't create snapshots pre-garbled we still deallocate blocks we shouldn't, but at least we no longer start snapshots off pointing at junk
--- a/dat.h
+++ b/dat.h
@@ -272,6 +272,7 @@
Oclearb, /* free block ptr if exists */
Oclobber, /* remove file if it exists */
Owstat, /* update kvp dirent */
+ Oretag, /* reference a snap id */
Nmsgtype, /* maximum message type */
};
--- a/fns.h
+++ b/fns.h
@@ -67,7 +67,7 @@
void clunkmount(Mount*);
char* updatesnap(Tree**, Tree*, char*);
-char* labelsnap(Tree*, char*, int);
+char* tagsnap(Tree*, char*, int);
char* delsnap(Tree*, vlong, char*);
char* freedl(Dlist*, int);
Tree* opensnap(char*, int*);
@@ -144,6 +144,7 @@
void dlist2kv(Dlist*, Kvp*, char*, int);
void lbl2kv(char*, vlong, uint, Kvp*, char*, int);
void link2kv(vlong, vlong, Kvp*, char*, int);
+void retag2kv(vlong, int, int, Kvp*, char*, int);
void tree2kv(Tree*, Kvp*, char*, int);
int kv2dir(Kvp*, Xdir*);
@@ -156,7 +157,7 @@
char* packbp(char*, int, Bptr*);
char* packdkey(char*, int, vlong, char*);
char* packdval(char*, int, Xdir*);
-char* packlabel(char*, int, char*);
+char* packlbl(char*, int, char*);
char* packsnap(char*, int, vlong);
char* packsuper(char*, int, vlong);
char* packtree(char*, int, Tree*);
--- a/fs.c
+++ b/fs.c
@@ -73,7 +73,7 @@
unlock(&fs->mountlk);
return;
}
- if((e = labelsnap(t, a->new, a->mutable)) != nil){
+ if((e = tagsnap(t, a->new, a->mutable)) != nil){
fprint(a->fd, "snap: error creating '%s': %s\n", a->new, e);
unlock(&fs->mountlk);
return;
--- a/pack.c
+++ b/pack.c
@@ -398,6 +398,21 @@
}
void
+retag2kv(vlong gen, int dlbl, int dsucc, Kvp *kv, char *buf, int nbuf)
+{
+ char *p;
+
+ kv->k = buf;
+ if((p = packsnap(buf, nbuf, gen)) == nil)
+ abort();
+ kv->nk = p - buf;
+ kv->v = p;
+ p[0] = dlbl;
+ p[1] = dsucc;
+ kv->nv = 2;
+}
+
+void
link2kv(vlong gen, vlong succ, Kvp *kv, char *buf, int nbuf)
{
char *p;
@@ -450,7 +465,7 @@
}
char*
-packlabel(char *p, int sz, char *name)
+packlbl(char *p, int sz, char *name)
{
int n;
--- a/ream.c
+++ b/ream.c
@@ -140,7 +140,7 @@
t.nlbl = 1;
t.ht = 1;
t.gen = fs->nextgen++;
- t.prev = -1ULL;
+ t.prev = 0;
t.bp = a->bp;
p = packtree(p, e - p, &t);
kv.nv = p - kv.v;
@@ -155,11 +155,11 @@
kv.nk = p - kv.k;
kv.v = p;
memset(&t, 0, sizeof(Tree));
- t.nsucc = 1;
+ t.nsucc = 0;
t.nlbl = 1;
t.ht = 1;
t.gen = fs->nextgen++;
- t.prev = -1ULL;
+ t.prev = 0;
t.bp = r->bp;
p = packtree(p, e - p, &t);
kv.nv = p - kv.v;
--- a/snap.c
+++ b/snap.c
@@ -321,7 +321,7 @@
m[nm].op = Odelete;
m[nm].k = buf[nm];
- if((e = packlabel(buf[nm], sizeof(buf[nm]), name)) == nil)
+ if((e = packlbl(buf[nm], sizeof(buf[nm]), name)) == nil)
return Ename;
m[nm].nk = e - m[nm].k;
m[nm].v = nil;
@@ -359,7 +359,7 @@
* will show up in the dump.
*/
char*
-labelsnap(Tree *t, char *name, int mutable)
+tagsnap(Tree *t, char *name, int mutable)
{
char buf[3][Kvmax];
Msg m[3];
@@ -381,31 +381,23 @@
n->nsucc = 0;
n->ht = t->ht;
n->bp = t->bp;
- n->prev = t->gen;
+ n->prev = t->prev;
n->base = t->gen;
n->gen = aincv(&fs->nextgen, 1);
n->memgen = aincv(&fs->nextgen, 1);
- t->flag |= Tforked;
- t->nsucc++;
-
- m[i].op = Oinsert;
- tree2kv(t, &m[i], buf[i], sizeof(buf[i]));
+ m[i].op = Oretag;
+ retag2kv(t->gen, 0, 1, &m[i], buf[i], sizeof(buf[i]));
i++;
-
m[i].op = Oinsert;
- tree2kv(n, &m[i], buf[i], sizeof(buf[i]));
- i++;
-
- m[i].op = Oinsert;
lbl2kv(name, n->gen, 1, &m[i], buf[i], sizeof(buf[i]));
i++;
}else{
t->nlbl++;
- m[i].op = Oinsert;
- tree2kv(t, &m[i], buf[i], sizeof(buf[i]));
- i++;
+ m[i].op = Oretag;
+ retag2kv(t->gen, 1, 0, &m[i], buf[i], sizeof(buf[i]));
+ i++;
m[i].op = Oinsert;
lbl2kv(name, t->gen, 0, &m[i], buf[i], sizeof(buf[i]));
i++;
@@ -426,15 +418,15 @@
char buf[4][Kvmax], *e;
Msg m[4];
Tree *t;
+ int i;
if(!o->dirty)
return nil;
/* update the old kvp */
- o->nsucc++;
+ o->gen, o->nsucc, o->nlbl, o->bp);
o->nlbl--;
- m[0].op = Oinsert;
- tree2kv(o, &m[0], buf[0], sizeof(buf[0]));
+ o->nsucc++;
/* create the new one */
@@ -448,17 +440,31 @@
t->ht = o->ht;
t->bp = o->bp;
t->base = o->base;
- t->prev = o->gen;
+ if(o->nlbl == 0 && o->nsucc == 1)
+ t->prev = o->prev;
+ else
+ t->prev = o->gen;
t->gen = o->memgen;
t->memgen = aincv(&fs->nextgen, 1);
- m[1].op = Oinsert;
- tree2kv(t, &m[1], buf[1], sizeof(buf[1]));
- m[2].op = Oinsert;
- link2kv(t->prev, t->gen, &m[2], buf[2], sizeof(buf[2]));
- m[3].op = Oinsert;
- lbl2kv(lbl, t->gen, Lmut, &m[3], buf[3], sizeof(buf[3]));
- if((e = btupsert(&fs->snap, m, 4)) != nil){
+ i = 0;
+ m[i].op = Oretag;
+ retag2kv(o->gen, -1, 1, &m[i], buf[i], sizeof(buf[i]));
+ i++;
+
+ m[i].op = Oinsert;
+ tree2kv(t, &m[i], buf[i], sizeof(buf[i]));
+ i++;
+
+ m[i].op = Oinsert;
+ link2kv(t->prev, t->gen, &m[i], buf[i], sizeof(buf[i]));
+ i++;
+
+ m[i].op = Oinsert;
+ lbl2kv(lbl, t->gen, Lmut, &m[i], buf[i], sizeof(buf[i]));
+ i++;
+
+ if((e = btupsert(&fs->snap, m, i)) != nil){
free(t);
return e;
}
@@ -467,10 +473,8 @@
o->dirty = 0;
/* this was the last ref to the snap */
- if(o->nlbl == 0 && o->nsucc == 1){
- t->prev = o->prev;
+ if(o->nlbl == 0 && o->nsucc == 1)
delsnap(o, -1, nil);
- }
closesnap(o);
asetp(r, t);
return nil;
@@ -490,7 +494,7 @@
Key k;
/* Klabel{"name"} => Ksnap{id} */
- if((p = packlabel(buf, sizeof(buf), label)) == nil)
+ if((p = packlbl(buf, sizeof(buf), label)) == nil)
return nil;
k.k = buf;
k.nk = p - buf;
--- a/tree.c
+++ b/tree.c
@@ -400,6 +400,8 @@
static int
apply(Kvp *kv, Msg *m, char *buf, int nbuf)
{
+ Tree t;
+
switch(m->op){
case Oclearb:
case Odelete:
@@ -412,6 +414,13 @@
case Owstat:
assert(keycmp(kv, m) == 0);
statupdate(kv, m);
+ return 1;
+ case Oretag:
+ assert(m->nv == 2);
+ unpacktree(&t, kv->v, kv->nv);
+ t.nlbl += m->v[0];
+ t.nsucc += m->v[1];
+ packtree(kv->v, kv->nv, &t);
return 1;
default:
abort();