shithub: gefs

Download patch

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;
 	}