shithub: gefs

Download patch

ref: ff9b3fe8899798ef13666ebc763053f1fd5dee72
parent: 66a2bf506102bfc0119f8899b997d0f0be8cebfb
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Nov 9 16:42:43 EST 2023

snap: correct snap refcounting, relink open mounts

--- a/snap.c
+++ b/snap.c
@@ -271,10 +271,12 @@
 delsnap(Tree *t, vlong succ, char *name)
 {
 	char buf[4][Kvmax], *e;
+	int nm, deltree;
+	Mount *mnt;
 	Msg m[4];
-	int nm;
 
 	nm = 0;
+	deltree = 0;
 	if(name != nil){
 		if(strcmp(name, "dump") == 0
 		|| strcmp(name, "empty") == 0
@@ -293,6 +295,7 @@
 	}
  
 	if(t->nlbl == 0 && t->nref <= 1){
+		deltree = 1;
 		m[nm].op = Orelink;
 		retag2kv(t->pred, succ, 0, 0, &m[nm], buf[nm], sizeof(buf[nm]));
 		nm++;
@@ -309,10 +312,6 @@
 		m[nm].v = nil;
 		m[nm].nv = 0;
 		nm++;
-	}else{
-		m[nm].op = Oinsert;
-		tree2kv(t, &m[nm], buf[nm], sizeof(buf[nm]));
-		nm++;
 	}
 	assert(nm <= nelem(m));
 	if((e = flushdlcache(1)) != nil)
@@ -321,6 +320,14 @@
 		return e;
 	if((e = reclaimblocks(t->gen, succ, t->pred)) != nil)
 		return e;
+	if(deltree){
+		for(mnt = fs->mounts; mnt != nil; mnt = mnt->next){
+			if(mnt->root->gen == t->succ)
+				mnt->root->pred = t->pred;
+			if(mnt->root->gen == t->pred)
+				mnt->root->succ = t->succ;
+		}
+	}
 	return nil;
 }
 
@@ -417,10 +424,6 @@
 	t->ht = o->ht;
 	t->bp = o->bp;
 	t->succ = -1;
-	if(o->nlbl == 0 && o->nref == 1)
-		t->pred = o->pred;
-	else
-		t->pred = o->gen;
 	t->base = o->base;
 	t->gen = o->memgen;
 	t->memgen = aincv(&fs->nextgen, 1);
@@ -427,8 +430,15 @@
 
 	i = 0;
 	m[i].op = Orelink;
-	retag2kv(o->gen, t->gen, -1, 1, &m[i], buf[i], sizeof(buf[i]));
+	if(o->nlbl == 0 && o->nref == 1){
+		t->pred = o->pred;
+		retag2kv(t->pred, t->gen, 0, 0, &m[i], buf[i], sizeof(buf[i]));
+	}else{
+		t->pred = o->gen;
+		retag2kv(t->pred, t->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++;