shithub: gefs

Download patch

ref: 8fad4df88ae048a8317f1633cdc47fbaf17d896b
parent: 3d5ff2d9beb0bdf1aef5ab7afca578ebe4f55795
author: Ori Bernstein <[email protected]>
date: Thu Oct 12 18:18:37 EDT 2023

gefs: put tree roots on the deferred reclamation list too

--- a/blk.c
+++ b/blk.c
@@ -950,7 +950,8 @@
 	}
 
 	if((f = malloc(sizeof(Bfree))) == nil)
-		return;
+		abort();
+	f->op = DFblk;
 	f->bp = bp;
 	if(b != nil)
 		f->b = holdblk(b);
@@ -996,22 +997,30 @@
 			return;
 	}
 	p = asetp(&fs->limbo[(ge+1)%3], nil);
-	asetl(&fs->epoch, (ge+1) % 3);
+	asetl(&fs->epoch, (ge+1)%3);
 
-	while(p != nil){
+	for(; p != nil; p = n){
 		n = p->next;
-		a = getarena(p->bp.addr);
-		qe.op = Qfree;
-		qe.bp = p->bp;
-		qe.b = nil;
-		qe.qgen = agetv(&fs->qgen);
-		qput(a->sync, qe);
-		if(p->b != nil){
-			setflag(p->b, Bfreed);
-			dropblk(p->b);
+		switch(p->op){
+		case DFtree:
+			free(p->t);
+			break;
+		case DFblk:
+			a = getarena(p->bp.addr);
+			qe.op = Qfree;
+			qe.bp = p->bp;
+			qe.b = nil;
+			qe.qgen = agetv(&fs->qgen);
+			qput(a->sync, qe);
+			if(p->b != nil){
+				setflag(p->b, Bfreed);
+				dropblk(p->b);
+			}
+			break;
+		default:
+			abort();
 		}
 		free(p);
-		p = n;
 	}
 }
 
--- a/dat.h
+++ b/dat.h
@@ -406,8 +406,15 @@
 	char	buf[Bufspc];
 };
 
+enum {
+	DFblk,
+	DFtree,
+};
+
 struct Bfree {
 	Bfree	*next;
+	int	op;
+	Tree	*t;
 	Blk	*b;
 	Bptr	bp;
 };
--- a/snap.c
+++ b/snap.c
@@ -468,7 +468,7 @@
 		abort();
 	if(unpacktree(t, kv.v, kv.nv) == nil)
 		abort();
-	ainc(&t->memref);
+	t->memref = 1;
 	return t;
 Error:
 	free(t);
@@ -482,10 +482,18 @@
 void
 closesnap(Tree *t)
 {
+	Bfree *f;
+	ulong ge;
+
 	if(t == nil || adec(&t->memref) != 0)
 		return;
-	assert(!t->dirty);
-	free(t);
+	if((f = malloc(sizeof(Bfree))) == nil)
+		abort();
+	f->op = DFtree;
+	f->t = t;
+	ge = agetl(&fs->epoch);
+	f->next = fs->limbo[ge];
+	fs->limbo[ge] = f;
 }
 
 char*