shithub: gefs

Download patch

ref: 7f8f7c4e79284a1d6657869d4b219efaf1118492
parent: f4834c699a4e3c1782aeefe85e6e48e7473e505a
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Nov 6 23:51:24 EST 2023

snap: fix up links forward, clean up code, fix refs correctly

--- a/dat.h
+++ b/dat.h
@@ -271,7 +271,8 @@
 	Oclearb,	/* free block ptr if exists */
 	Oclobber,	/* remove file if it exists */
 	Owstat,		/* update kvp dirent */
-	Oretag,		/* reference a snap id */
+	Orelink,	/* rechain forwards */
+	Oreprev,	/* rechain backwards */
 	Nmsgtype,	/* maximum message type */
 };
 
--- a/dump.c
+++ b/dump.c
@@ -131,10 +131,20 @@
 		}
 		break;
 	case Ksnap:	/* name[n] => dent[16] ptr[16]:	snapshot root */
-		if(unpacktree(&t, v->v, v->nv) == nil)
-			n = fmtprint(fmt, "corrupt tree");
-		else
-			n = fmtprint(fmt, "<tree>");
+		switch(op){
+		case Orelink:
+		case Oreprev:
+			n = fmtprint(fmt, "gen: %lld, dlbl: %d, dref: %d", UNPACK64(v->v), v->v[8], v->v[9]);
+			break;
+		case Oinsert:
+			if(unpacktree(&t, v->v, v->nv) == nil)
+				n = fmtprint(fmt, "corrupt tree");
+			else
+				n = fmtprint(fmt, "<tree>");
+			break;
+		default:
+			n = fmtprint(fmt, "?? unknown op %d", op);
+		}
 		break;
 	case Klabel:
 		n = fmtprint(fmt, "snap id:\"%lld\"", UNPACK64(v->v+1));
@@ -169,7 +179,10 @@
 	[Oinsert]	"Oinsert",
 	[Odelete]	"Odelete",
 	[Oclearb]	"Oclearb",
+	[Oclobber]	"Oclobber",
 	[Owstat]	"Owstat",
+	[Orelink]	"Orelink",
+	[Oreprev]	"Oreprev",
 	};
 	Msg *m;
 	int f, n;
@@ -351,7 +364,7 @@
 	fprint(fd, "\tgen:\t%lld\n", t->gen);
 	fprint(fd, "\tbase\t%lld\n", t->base);
 	fprint(fd, "\tpred:\t%lld\n", t->pred);
-	fprint(fd, "\tpred:\t%lld\n", t->succ);
+	fprint(fd, "\tsucc:\t%lld\n", t->succ);
 	fprint(fd, "\tnref:\t%d\n", t->nref);
 	fprint(fd, "\tnlbl:\t%d\n", t->nlbl);
 	fprint(fd, "\tht:\t%d\n", t->ht);
--- a/fns.h
+++ b/fns.h
@@ -143,7 +143,7 @@
 void	dlist2kv(Dlist*, Kvp*, char*, int);
 void	lbl2kv(char*, vlong, uint, Kvp*, char*, int);
 void	link2kv(vlong, vlong, Kvp*, char*, int);
-void	retag2kv(vlong, vlong, vlong, int, int, Kvp*, char*, int);
+void	retag2kv(vlong, vlong, int, int, Kvp*, char*, int);
 void	tree2kv(Tree*, Kvp*, char*, int);
 
 int	kv2dir(Kvp*, Xdir*);
--- a/fs.c
+++ b/fs.c
@@ -36,9 +36,8 @@
 static void
 snapfs(Amsg *a)
 {
-	Mount *mnt, *old;
-	vlong succ;
 	Tree *t, *s;
+	Mount *mnt;
 	char *e;
 
 	lock(&fs->mountlk);
@@ -2311,7 +2310,7 @@
 {
 	Amsg *a;
 
-	while(0){
+	while(1){
 		sleep(5000);
 		a = mallocz(sizeof(Amsg), 1);
 		if(a == nil){
--- a/pack.c
+++ b/pack.c
@@ -398,11 +398,11 @@
 }
 
 void
-retag2kv(vlong gen, vlong pred, vlong succ, int dlbl, int dref, Kvp *kv, char *buf, int nbuf)
+retag2kv(vlong gen, vlong link, int dlbl, int dref, Kvp *kv, char *buf, int nbuf)
 {
 	char *p;
 
-	assert(nbuf >= 8+8+1+1);
+	assert(nbuf >= 8+1+1);
 	kv->k = buf;
 	if((p = packsnap(buf, nbuf, gen)) == nil)
 		abort();
@@ -409,12 +409,10 @@
 	kv->nk = p - buf;
 
 	kv->v = p;
-	PACK64(p, pred);	p += 8;
-	PACK64(p, succ);	p += 8;
+	PACK64(p, link);	p += 8;
 	*p = dlbl;		p += 1;
 	*p = dref;		p += 1;
 	kv->nv = p - kv->v;
-assert(kv->nv == 18);
 }
 
 void
--- a/ream.c
+++ b/ream.c
@@ -121,7 +121,8 @@
 	t.nlbl = 2;
 	t.ht = 1;
 	t.gen = fs->nextgen++;
-	t.pred = -1ULL;
+	t.pred = 0;
+	t.succ = 2;
 	t.bp = r->bp;
 	p = packtree(p, e - p, &t);
 	kv.nv = p - kv.v;
@@ -141,7 +142,7 @@
 	t.ht = 1;
 	t.gen = fs->nextgen++;
 	t.pred = 0;
-	t.succ = 2;
+	t.succ = -1;
 	t.bp = a->bp;
 	p = packtree(p, e - p, &t);
 	kv.nv = p - kv.v;
--- a/snap.c
+++ b/snap.c
@@ -270,8 +270,8 @@
 char*
 delsnap(Tree *t, vlong succ, char *name)
 {
-	char buf[2][Kvmax], *e;
-	Msg m[2];
+	char buf[4][Kvmax], *e;
+	Msg m[4];
 	int nm;
 
 	nm = 0;
@@ -293,6 +293,14 @@
 	}
  
 	if(t->nlbl == 0 && t->nref <= 1){
+		m[nm].op = Orelink;
+		retag2kv(t->pred, succ, 0, 0, &m[nm], buf[nm], sizeof(buf[nm]));
+		nm++;
+		if(t->succ != -1){
+			m[nm].op = Oreprev;
+			retag2kv(t->succ, t->pred, 0, 0, &m[nm], buf[nm], sizeof(buf[nm]));
+			nm++;
+		}
 		m[nm].op = Odelete;
 		m[nm].k = buf[nm];
 		if((e = packsnap(buf[nm], sizeof(buf[nm]), t->gen)) == nil)
@@ -306,6 +314,7 @@
 		tree2kv(t, &m[nm], buf[nm], sizeof(buf[nm]));
 		nm++;
 	}
+	assert(nm <= nelem(m));
 	if((e = flushdlcache(1)) != nil)
 		return e;
 	if((e = btupsert(&fs->snap, m, nm)) != nil)
@@ -349,8 +358,8 @@
 		n->gen = aincv(&fs->nextgen, 1);
 		n->memgen = aincv(&fs->nextgen, 1);
 
-		m[i].op = Oretag;
-		retag2kv(t->gen, t->pred, t->succ, 0, 1, &m[i], buf[i], sizeof(buf[i]));
+		m[i].op = Orelink;
+		retag2kv(t->gen, t->succ, 0, 1, &m[i], buf[i], sizeof(buf[i]));
 		i++;
 		m[i].op = Oinsert;
 		lbl2kv(name, n->gen, 1, &m[i], buf[i], sizeof(buf[i]));
@@ -361,9 +370,10 @@
 	}else{
 		t->nlbl++;
 
-		m[i].op = Oretag;
-		retag2kv(t->gen, t->pred, t->succ, 1, 0, &m[i], buf[i], sizeof(buf[i]));
+		m[i].op = Orelink;
+		retag2kv(t->gen, t->succ, 1, 0, &m[i], buf[i], sizeof(buf[i]));
 		i++;
+
 		m[i].op = Oinsert;
 		t->pred = t->gen;
 		t->nlbl++;
@@ -406,27 +416,25 @@
 	t->nref = 0;
 	t->ht = o->ht;
 	t->bp = o->bp;
-	t->base = o->base;
+	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);
 
 	i = 0;
-	m[i].op = Oretag;
-	retag2kv(o->gen, o->pred, t->gen, -1, 1, &m[i], buf[i], sizeof(buf[i]));
+	m[i].op = Orelink;
+	retag2kv(o->gen, 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++;
-
 	m[i].op = Oinsert;
 	lbl2kv(lbl, t->gen, Lmut, &m[i], buf[i], sizeof(buf[i]));
 	i++;
-
 	if((e = btupsert(&fs->snap, m, i)) != nil){
 		free(t);
 		return e;
@@ -437,7 +445,7 @@
 
 	/* this was the last ref to the snap */
 	if(o->nlbl == 0 && o->nref == 1)
-		delsnap(o, -1, nil);
+		delsnap(o, t->gen, nil);
 	closesnap(o);
 	asetp(r, t);
 	return nil;
--- a/tree.c
+++ b/tree.c
@@ -400,9 +400,9 @@
 static int
 apply(Kvp *kv, Msg *m, char *buf, int nbuf)
 {
+	vlong *pv;
 	char *p;
 	Tree t;
-	vlong v;
 
 	switch(m->op){
 	case Oclearb:
@@ -417,13 +417,15 @@
 		assert(keycmp(kv, m) == 0);
 		statupdate(kv, m);
 		return 1;
-	case Oretag:
+	case Orelink:
+	case Oreprev:
 		unpacktree(&t, kv->v, kv->nv);
 		p = m->v;
-		t.pred = UNPACK64(p);	p += 8;
-		t.succ = UNPACK64(p);	p += 8;
+		pv = (m->op == Orelink) ? &t.succ : &t.pred;
+		*pv = UNPACK64(p);	p += 8;
 		t.nlbl += *p;		p++;
 		t.nref += *p;		p++;
+		assert(t.nlbl >= 0 && t.nref >= 0);
 		assert(p == m->v + m->nv);
 		packtree(kv->v, kv->nv, &t);
 		return 1;
@@ -1424,8 +1426,9 @@
 			if(p[i].vi == -1)
 				getval(b, ++p[i].vi, &v);
 			p[i].bi = bufsearch(b, &s->kv, &m, &same);
-			if(p[i].bi == -1 || !same || !s->first){
+			if(p[i].bi == -1){
 				p[i].bi++;
+			}else if(!same || !s->first){
 				/* scan past repeated messages */
 				while(p[i].bi < p[i].b->nbuf){
 					getmsg(p[i].b, p[i].bi, &c);