shithub: gefs

Download patch

ref: 0ce6791400f1db6585ec089570b7f015d6c034ce
parent: 093c8160b677469b68ba957a2c1f6c9aa093e9d2
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Oct 27 10:33:53 EDT 2023

fs: make iterating a tree unaffected by mutations

--- a/check.c
+++ b/check.c
@@ -200,7 +200,7 @@
 		return 0;
 	}
 	while(1){
-		if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+		if((e = btnext(&s, &s.kv)) != nil){
 			fprint(fd, "invalid snapshot tree: %s\n", e);
 			ok = 0;
 			break;
@@ -227,5 +227,6 @@
 			ok = 0;
 		dropblk(b);
 	}
+	btexit(&s);
 	return ok;
 }
--- a/cons.c
+++ b/cons.c
@@ -208,9 +208,9 @@
 			goto Out;
 		}
 		while(1){
-			if((e = btnext(t, &s, &kv)) != nil){
+			if((e = btnext(&s, &kv)) != nil){
 				fprint(fd, "scan failed: %s\n", e);
-				btexit(t, &s);
+				btexit(&s);
 				goto Out;
 			}
 			if(s.done)
@@ -217,7 +217,7 @@
 				break;
 			fprint(fd, "%P\n", &kv);
 		}
-		btexit(t, &s);
+		btexit(&s);
 	}
 Out:
 	closesnap(t);
--- a/dat.h
+++ b/dat.h
@@ -665,6 +665,7 @@
 	char	done;
 	char	overflow;
 	char	present;
+	int	ht;
 	Kvp	kv;
 	Key	pfx;
 	char	kvbuf[Kvmax];
--- a/dump.c
+++ b/dump.c
@@ -410,11 +410,11 @@
 		btnewscan(&s, pfx, sz);
 		if((e = btenter(&fs->snap, &s)) != nil){
 			fprint(fd, "scan: %s\n", e);
-			btexit(&fs->snap, &s);
+			btexit(&s);
 			return;
 		}
 		while(1){
-			if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+			if((e = btnext(&s, &s.kv)) != nil){
 				fprint(fd, "scan: %s\n", e);
 				break;
 			}
@@ -422,7 +422,7 @@
 				break;
 			fprint(fd, "label: %P\n", &s.kv);
 		}
-		btexit(&fs->snap, &s);
+		btexit(&s);
 	}
 
 	/* dump the snapshots */
@@ -436,11 +436,11 @@
 	btnewscan(&s, pfx, sz);
 	if((e = btenter(&fs->snap, &s)) != nil){
 		fprint(fd, "scan: %s\n", e);
-		btexit(&fs->snap, &s);
+		btexit(&s);
 		return;
 	}
 	while(1){
-		if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+		if((e = btnext(&s, &s.kv)) != nil){
 			fprint(fd, "scan: %s\n", e);
 			break;
 		}
@@ -453,7 +453,7 @@
 		}
 		showtreeroot(fd, &t);
 	}
-	btexit(&fs->snap, &s);
+	btexit(&s);
 }
 
 void
@@ -477,11 +477,11 @@
 	btnewscan(&s, pfx, sz);
 	if((err = btenter(&fs->snap, &s)) != nil){
 		fprint(fd, "scan: %s\n", err);
-		btexit(&fs->snap, &s);
+		btexit(&s);
 		return;
 	}
 	while(1){
-		if((e = btnext(&fs->snap, &s, &s.kv)) != nil){
+		if((e = btnext(&s, &s.kv)) != nil){
 			fprint(fd, "scan: %s\n", e);
 			break;
 		}
@@ -503,7 +503,7 @@
 			dropblk(b);
 		}
 	}
-	btexit(&fs->snap, &s);
+	btexit(&s);
 }
 
 void
--- a/fns.h
+++ b/fns.h
@@ -66,6 +66,7 @@
 char*	updatesnap(Tree**, Tree*, char*);
 char*	labelsnap(Tree*, char*);
 char*	delsnap(Tree*, vlong, char*);
+char*	freedl(Dlist*, int);
 Tree*	opensnap(char*);
 vlong	successor(vlong);
 
@@ -92,8 +93,8 @@
 char*	btlookup(Tree*, Key*, Kvp*, char*, int);
 void	btnewscan(Scan*, char*, int);
 char*	btenter(Tree*, Scan*);
-char*	btnext(Tree*, Scan*, Kvp*);
-void	btexit(Tree*, Scan*);
+char*	btnext(Scan*, Kvp*);
+void	btexit(Scan*);
 
 int	checkflag(Blk *b, int);
 void	setflag(Blk *b, int);
--- a/fs.c
+++ b/fs.c
@@ -1589,12 +1589,12 @@
 	btnewscan(&s, pfx, sizeof(pfx));
 	if((e = btenter(t, &s)) != nil)
 		goto Out;
-	if((e = btnext(t, &s, &s.kv)) != nil)
+	if((e = btnext(&s, &s.kv)) != nil)
 		goto Out;
 	if(!s.done)
 		e = Enempty;
 Out:
-	btexit(t, &s);
+	btexit(&s);
 	return e;
 }
 
@@ -1813,7 +1813,7 @@
 	if((e = btenter(&fs->snap, s)) != nil)
 		return e;
 	while(1){
-		if((e = btnext(&fs->snap, s, &s->kv)) != nil)
+		if((e = btnext(s, &s->kv)) != nil)
 			return e;
 		if(s->done)
 			break;
@@ -1827,7 +1827,7 @@
 		p += ns;
 		n -= ns;
 	}
-	btexit(&fs->snap, s);
+	btexit(s);
 	r->count = p - r->data;
 	return nil;
 }
@@ -1874,7 +1874,7 @@
 	if((e = btenter(t, s)) != nil)
 		return e;
 	while(1){
-		if((e = btnext(t, s, &s->kv)) != nil)
+		if((e = btnext(s, &s->kv)) != nil)
 			return e;
 		if(s->done)
 			break;
@@ -1885,7 +1885,7 @@
 		p += ns;
 		n -= ns;
 	}
-	btexit(t, s);
+	btexit(s);
 	r->count = p - r->data;
 	return nil;
 }
--- a/snap.c
+++ b/snap.c
@@ -145,7 +145,7 @@
 	fs->dlhead = dl;
 }
 
-static char*
+char*
 freedl(Dlist *dl, int docontents)
 {
 	Bptr bp, fb;
@@ -242,19 +242,19 @@
 	btnewscan(&s, pfx, sizeof(pfx));
 	if((e = btenter(&fs->snap, &s)) != nil)
 		goto Err;
-	if((e = btnext(&fs->snap, &s, &s.kv)) != nil)
+	if((e = btnext(&s, &s.kv)) != nil)
 		goto Err;
 	if(!s.done)
 		kv2link(&s.kv, &id, &succ);
-	if((e = btnext(&fs->snap, &s, &s.kv)) != nil)
+	if((e = btnext(&s, &s.kv)) != nil)
 		goto Err;
 	if(!s.done)
 		sysfatal("multiple successors in cleanup");
-	btexit(&fs->snap, &s);
+	btexit(&s);
 	return succ;
 Err:
 	fprint(2, "error getting snap successor: %s", e);
-	btexit(&fs->snap, &s);
+	btexit(&s);
 	return -1;
 }
 
@@ -272,7 +272,7 @@
 	if((e = btenter(&fs->snap, &s)) != nil)
 		return e;
 	while(1){
-		if((e = btnext(&fs->snap, &s, &s.kv)) != nil)
+		if((e = btnext(&s, &s.kv)) != nil)
 			break;
 		if(s.done)
 			break;
@@ -295,7 +295,7 @@
 		if(e != nil)
 			break;
 	}
-	btexit(&fs->snap, &s);
+	btexit(&s);
 	return e;
 }
 
--- a/tree.c
+++ b/tree.c
@@ -1397,6 +1397,7 @@
 
 	if(s->done)
 		return nil;
+	s->ht = t->ht;
 	if((s->path = calloc(t->ht, sizeof(Scanp))) == nil)
 		return Enomem;
 	p = s->path;
@@ -1431,7 +1432,7 @@
 }
 
 char *
-btnext(Tree *t, Scan *s, Kvp *r)
+btnext(Scan *s, Kvp *r)
 {
 	int i, j, h, ok, start, srcbuf;
 	Scanp *p;
@@ -1442,7 +1443,7 @@
 	/* load up the correct blocks for the scan */
 Again:
 	p = s->path;
-	h = t->ht;
+	h = s->ht;
 	start = h;
 	srcbuf = -1;
 	if(s->done)
@@ -1517,11 +1518,11 @@
 }
 
 void
-btexit(Tree *t, Scan *s)
+btexit(Scan *s)
 {
 	int i;
 
-	for(i = 0; i < t->ht; i++)
+	for(i = 0; i < s->ht; i++)
 		dropblk(s->path[i].b);
 	free(s->path);
 }