ref: 439759e82ed9df31cc192defdb86189727109468
parent: e81148096520ebbbcbc0b449184a2c9d62869883
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Oct 26 19:19:37 EDT 2023
snap: fix snapshotting bugs
--- a/blk.c
+++ b/blk.c
@@ -794,7 +794,7 @@
return nil;
if((b = cachepluck()) == nil)
return nil;
- initblk(b, bp, t->gen, ty);
+ initblk(b, bp, t->memgen, ty);
b->alloced = getcallerpc(&t);
return b;
}
@@ -944,7 +944,7 @@
Bfree *f;
ulong ge;
- if(t != nil && t != &fs->snap && bp.gen <= t->prev){
+ if(t != nil && t != &fs->snap && bp.gen <= t->gen){
killblk(t, bp);
return;
}
--- a/dat.h
+++ b/dat.h
@@ -404,6 +404,7 @@
int nlbl; /* number of labels referring to us */
int ht; /* height of the tree */
Bptr bp; /* block pointer of root */
+ vlong memgen; /* wip next generation */
vlong gen; /* generation */
vlong prev; /* previous snapshot */
--- a/snap.c
+++ b/snap.c
@@ -62,7 +62,7 @@
uint h;
h = ihash(gen) ^ ihash(bgen);
- for(dl = fs->dlcache[h %fs->dlcmax]; dl != nil; dl = dl->chain)
+ for(dl = fs->dlcache[h % fs->dlcmax]; dl != nil; dl = dl->chain)
if(dl->gen == gen && dl->bgen == bgen)
break;
if(dl != nil)
@@ -127,11 +127,8 @@
Dlist *dt;
dlcachedel(dl, 0);
- dl->cprev = nil;
- dl->cnext = fs->dlhead;
- fs->dlhead = dl;
- while(fs->ctail != nil && fs->dlcount >= fs->dlcmax){
+ while(fs->dltail != nil && fs->dlcount >= fs->dlcmax){
dt = fs->dltail;
dlsync(dt);
dlcachedel(dt, 1);
@@ -138,12 +135,20 @@
dropblk(dt->ins);
free(dt);
}
+
+ dl->cprev = nil;
+ dl->cnext = fs->dlhead;
+ if(fs->dltail == nil)
+ fs->dltail = dl;
+ if(fs->dlhead != nil)
+ fs->dlhead->cprev = dl;
+ fs->dlhead = dl;
}
static char*
freedl(Dlist *dl, int docontents)
{
- Bptr bp;
+ Bptr bp, fb;
Blk *b;
char *p;
@@ -154,10 +159,10 @@
return Efs;
if(docontents){
for(p = b->data; p != b->data+b->deadsz; p += 8){
- if(blkdealloc(UNPACK64(p)) == -1){
- dropblk(b);
- return Efs;
- }
+ fb.addr = UNPACK64(p);
+ fb.hash = -1;
+ fb.gen = -1;
+ freeblk(nil, nil, fb);
}
}
bp = b->deadp;
@@ -407,11 +412,9 @@
t->nsucc = 0;
t->ht = o->ht;
t->bp = o->bp;
- if(o->nlbl == 0 && o->nsucc == 1)
- t->prev = o->prev;
- else
- t->prev = o->gen;
- t->gen = aincv(&fs->nextgen, 1);
+ 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]));
@@ -428,8 +431,10 @@
o->dirty = 0;
/* this was the last ref to the snap */
- if(o->nlbl == 0 && o->nsucc == 1)
+ if(o->nlbl == 0 && o->nsucc == 1){
+ t->prev = o->prev;
delsnap(o, t->gen, nil);
+ }
closesnap(o);
*r = t;
return nil;
@@ -469,6 +474,7 @@
if(unpacktree(t, kv.v, kv.nv) == nil)
abort();
t->memref = 1;
+ t->memgen = aincv(&fs->nextgen, 1);
return t;
Error:
free(t);
@@ -491,6 +497,7 @@
abort();
f->op = DFtree;
f->t = t;
+print("limbo %#p\n", t);
ge = agetl(&fs->epoch);
f->next = fs->limbo[ge];
fs->limbo[ge] = f;
@@ -537,7 +544,7 @@
if((dl = getdl(t->gen, bp.gen)) == nil)
return -1;
- if(dl->ins == nil || dl->ins->deadsz == Dlspc){
+ if(dl->ins == nil || Dlspc - dl->ins->deadsz < 8){
if((b = newblk(&fs->snap, Tdlist)) == nil){
putdl(dl);
return -1;
@@ -552,6 +559,7 @@
dl->tl = b->bp;
b->deadp = (Bptr){-1, -1, -1};
}
+ cacheins(b);
dl->hd = b->bp;
dl->ins = b;
}