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