shithub: gefs

Download patch

ref: 2ae0be32e919e3981e3c5f1012cb9bf68b9d858a
parent: 99c900d718ea1343036656b7384af56bcad2f28f
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Dec 22 21:47:19 EST 2021

wip: start processing deadlists.

--- a/blk.c
+++ b/blk.c
@@ -169,7 +169,7 @@
 }
 
 Blk*
-logappend(Oplog *ol, Arena *a, vlong off, vlong len, int op)
+logappend(Oplog *ol, Arena *a, vlong off, vlong len, vlong val, int op)
 {
 	Blk *pb, *lb;
 	vlong o;
@@ -220,7 +220,7 @@
 	PBIT64(p, off);
 	lb->logsz += 8;
 	if(op >= Log2wide){
-		PBIT64(p+8, len);
+		PBIT64(p+8, val);
 		lb->logsz += 8;
 	}
 	/* this gets overwritten by the next append */
@@ -244,10 +244,10 @@
 			break;
 		}
 	}
-	if((b = logappend(l, nil, bp.addr, Blksz, LogDead)) == nil)
+	if((b = logappend(l, nil, bp.addr, Blksz, bp.gen, LogDead)) == nil)
 		return -1;
-	if(l->head == -1)
-		l->head = b->bp.addr;
+	if(l->head.addr == -1)
+		l->head = b->bp;
 	if(l->tail != b)
 		l->tail = b;
 	return 0;
@@ -264,10 +264,10 @@
 {
 	Blk *b;
 
-	if((b = logappend(&a->log, a, off, Blksz, op)) == nil)
+	if((b = logappend(&a->log, a, off, Blksz, Blksz, op)) == nil)
 		return -1;
-	if(a->log.head == -1)
-		a->log.head = b->bp.addr;
+	if(a->log.head.addr == -1)
+		a->log.head = b->bp;
 	if(a->log.tail != b)
 		a->log.tail = b;
 	return 0;
@@ -274,21 +274,78 @@
 }
 
 int
+scandead(Bptr bp, int (*fn)(Bptr))
+{
+	vlong ent, off;
+	int op, i, n;
+	uvlong bh;
+	Bptr dead;
+	char *d;
+	Blk *b;
+
+Nextblk:
+	if((b = getblk(bp, GBnochk)) == nil)
+		return -1;
+	bh = GBIT64(b->data);
+	/* the hash covers the log and offset */
+	if(bh != siphash(b->data+8, Blkspc-8)){
+		werrstr("corrupt log");
+		return -1;
+	}
+	for(i = Loghdsz; i < Logspc; i += n){
+		d = b->data + i;
+		ent = GBIT64(d);
+		op = ent & 0xff;
+		off = ent & ~0xff;
+		n = (op >= Log2wide) ? 16 : 8;
+		switch(op){
+		case LogDead:
+			dead.addr = ent;
+			dead.hash = -1;
+			dead.gen = GBIT64(d+8);
+			fn(dead);
+			break;
+		case LogEnd:
+			dprint("log@%d: end\n", i);
+			/*
+			 * since we want the next insertion to overwrite
+			 * this, don't include the size in this entry.
+			 */
+			b->logsz = i;
+			return 0;
+		case LogChain:
+			bp.addr = off & ~0xff;
+			bp.hash = -1;
+			bp.gen = -1;
+			dprint("log@%d: chain %B\n", i, bp);
+			b->logsz = i+n;
+			goto Nextblk;
+			break;
+		default:
+			n = 0;
+			dprint("log@%d: log op %d\n", i, op);
+			abort();
+			break;
+		}
+	}
+	return 0;
+}
+
+int
 loadlog(Arena *a)
 {
-	vlong bp, ent, off, len;
+	vlong ent, off, len;
 	int op, i, n;
 	uvlong bh;
+	Bptr bp;
 	char *d;
 	Blk *b;
 
 
 	bp = a->log.head;
-
 Nextblk:
-	if((b = readblk(bp, 0)) == nil)
+	if((b = getblk(bp, GBnochk)) == nil)
 		return -1;
-	cacheblk(b);
 	bh = GBIT64(b->data);
 	/* the hash covers the log and offset */
 	if(bh != siphash(b->data+8, Blkspc-8)){
@@ -311,8 +368,10 @@
 			b->logsz = i;
 			return 0;
 		case LogChain:
-			bp = off & ~0xff;
-			dprint("log@%d: chain %llx\n", i, bp);
+			bp.addr = off & ~0xff;
+			bp.hash = -1;
+			bp.gen = -1;
+			dprint("log@%d: chain %B\n", i, bp);
 			b->logsz = i+n;
 			goto Nextblk;
 			break;
@@ -424,12 +483,11 @@
 		return -1;
 	}
 	hd = b;
-	ol.hash = -1;
-	ol.head = b->bp.addr;
+	ol.head = b->bp;
 	ol.tail = b;
 	b->logsz = Loghdsz;
 	for(i = 0; i < n; i++)
-		if((b = logappend(&ol, a, log[i].off, log[i].len, LogFree)) == nil)
+		if((b = logappend(&ol, a, log[i].off, log[i].len, log[i].len, LogFree)) == nil)
 			return -1;
 	p = b->data + b->logsz;
 	PBIT64(p, LogChain|graft);
@@ -438,12 +496,13 @@
 	if(syncblk(b) == -1)
 		return -1;
 
-	oldhd = a->log.head;
-	a->log.head = hd->bp.addr;
-	a->log.hash = blkhash(hd);
+	oldhd = a->log.head.addr;
+	a->log.head.addr = hd->bp.addr;
+	a->log.head.hash = blkhash(hd);
+	a->log.head.gen = -1;
 	ab = a->b;
-	PBIT64(ab->data + 0, a->log.head);
-	PBIT64(ab->data + 8, a->log.hash);
+	PBIT64(ab->data + 0, a->log.head.addr);
+	PBIT64(ab->data + 8, a->log.head.hash);
 	finalize(ab);
 	if(syncblk(ab) == -1)
 		return -1;
@@ -684,6 +743,7 @@
 getblk(Bptr bp, int flg)
 {
 	Blk *b;
+	uvlong h;
 
 	if((b = lookupblk(bp.addr)) != nil)
 		return cacheblk(b);
@@ -698,13 +758,14 @@
 		qunlock(&blklock);
 		return nil;
 	}
-	if(blkhash(b) != bp.hash){
+	h = blkhash(b);
+	if((flg&GBnochk) == 0 && h != bp.hash){
 		fprint(2, "corrupt block %B: %llx != %llx\n", bp, blkhash(b), bp.hash);
 		qunlock(&blklock);
 		abort();
 		return nil;
 	}
-	b->bp.hash = bp.hash;
+	b->bp.hash = h;
 	b->bp.gen = bp.gen;
 	cacheblk(b);
 	qunlock(&blklock);
--- a/dat.h
+++ b/dat.h
@@ -245,7 +245,7 @@
 enum {
 	GBraw	= 1<<0,
 	GBwrite	= 1<<1,
-	GBunchk	= 1<<2,
+	GBnochk	= 1<<2,
 };
 
 enum {
@@ -289,9 +289,14 @@
 	LogDead	,	/* deadlist a block */
 };
 
+struct Bptr {
+	vlong	addr;
+	vlong	hash;
+	vlong	gen;
+};
+
 struct Oplog {
-	vlong	head;	/* log head */
-	vlong	hash;	/* log head hash */
+	Bptr	head;
 	Blk	*tail;	/* tail block open for writing */
 };
 
@@ -312,12 +317,6 @@
 	QLock	*wrlk;	/* write lock on fd */
 	int	sz;	/* the size of the message buf */
 	uchar	buf[];
-};
-
-struct Bptr {
-	vlong	addr;
-	vlong	hash;
-	vlong	gen;
 };
 
 struct Tree {
--- a/dump.c
+++ b/dump.c
@@ -339,8 +339,7 @@
 		for(i = 0; i < Ndead; i++){
 			fprint(fd, "\tdeadlist %d\n", i);
 			fprint(fd, "\t\tprev:\t%llx\n", t.prev[i]);
-			fprint(fd, "\t\tfheadp:\t%llx\n", t.dead[i].head);
-			fprint(fd, "\t\tfheadh:\t%llx\n", t.dead[i].hash);
+			fprint(fd, "\t\tfhead:\t%B\n", t.dead[i].head);
 			if(t.dead[i].tail != nil){
 				fprint(fd, "\t\tftailp:%llx\n", t.dead[i].tail->bp.addr);
 				fprint(fd, "\t\tftailh:%llx\n", t.dead[i].tail->bp.hash);
--- a/fns.h
+++ b/fns.h
@@ -42,6 +42,7 @@
 void	loadfs(char*);
 int	sync(void);
 int	loadlog(Arena*);
+int	scandead(Bptr, int (*)(Bptr));
 int	endfs(void);
 int	compresslog(Arena*);
 void	setval(Blk*, int, Kvp*);
--- a/load.c
+++ b/load.c
@@ -22,8 +22,9 @@
 	if((b = readblk(o, 0)) == nil)
 		return -1;
 	a->b = b;
-	a->log.head = GBIT64(b->data+0);
-	a->log.hash = GBIT64(b->data+8);
+	a->log.head.addr = GBIT64(b->data+0);
+	a->log.head.hash = GBIT64(b->data+8);
+	a->log.head.gen = -1;
 	if(loadlog(a) == -1)
 		return -1;
 	if(compresslog(a) == -1)
--- a/mkfile
+++ b/mkfile
@@ -13,7 +13,7 @@
 	main.$O\
 	pack.$O\
 	ream.$O\
-	sync.$O\
+	snap.$O\
 	tree.$O\
 
 HFILES=\
--- a/pack.c
+++ b/pack.c
@@ -308,7 +308,7 @@
 unpacktree(Tree *t, char *p, int sz)
 {
 	int i, j;
-	Bptr bp;
+	Bptr bp, head;
 	Blk *b;
 
 	assert(sz >= Treesz);
@@ -319,11 +319,12 @@
 	t->bp.hash = GBIT64(p);		p += 8;
 	t->bp.gen = GBIT64(p);		p += 8;
 	for(i = 0; i < Ndead; i++){
-		t->prev[i] = GBIT64(p);		p += 8;
-		t->dead[i].head = GBIT64(p);	p += 8;
-		t->dead[i].hash = GBIT64(p);	p += 8;
-		bp.addr = GBIT64(p);		p += 8;
-		bp.hash = GBIT64(p);		p += 8;
+		t->prev[i] = GBIT64(p);	p += 8;
+		head.addr = GBIT64(p);	p += 8;
+		head.hash = GBIT64(p);	p += 8;
+		head.gen = -1;
+		bp.addr = GBIT64(p);	p += 8;
+		bp.hash = GBIT64(p);	p += 8;
 		bp.gen = -1;
 		if(bp.addr == -1)
 			continue;
@@ -332,6 +333,7 @@
 				putblk(t->dead[j].tail);
 			return nil;
 		}
+		t->dead[i].head = head;
 		t->dead[i].tail	= b;
 		cacheblk(b);		
 	}
@@ -342,6 +344,7 @@
 packtree(char *p, int sz, Tree *t)
 {
 	vlong tladdr, tlhash;
+	Bptr head;
 	Blk *tl;
 	int i;
 
@@ -362,11 +365,12 @@
 			tladdr = tl->bp.addr;
 			tlhash = tl->bp.hash;
 		}
-		PBIT64(p, t->prev[i]);		p += 8;
-		PBIT64(p, t->dead[i].head);	p += 8;
-		PBIT64(p, t->dead[i].hash);	p += 8;
-		PBIT64(p, tladdr);		p += 8;
-		PBIT64(p, tlhash);		p += 8;
+		head = t->dead[i].head;
+		PBIT64(p, t->prev[i]);	p += 8;
+		PBIT64(p, head.addr);	p += 8;
+		PBIT64(p, head.hash);	p += 8;
+		PBIT64(p, tladdr);	p += 8;
+		PBIT64(p, tlhash);	p += 8;
 	}
 	return p;
 }
--- a/ream.c
+++ b/ream.c
@@ -68,8 +68,9 @@
 	t.bp = r->bp;
 	for(i = 0; i < Ndead; i++){
 		t.prev[i] = -1;
-		t.dead[i].head = -1;
-		t.dead[i].hash = -1;
+		t.dead[i].head.addr = -1;
+		t.dead[i].head.hash = -1;
+		t.dead[i].head.gen = -1;
 		t.dead[i].tail = nil;
 	}
 	p = packtree(vbuf, sizeof(vbuf), &t);
@@ -90,7 +91,10 @@
 		sysfatal("ream: %r");
 	addr += Blksz;	/* arena header */
 
-	a->log.head = -1;
+	a->log.head.addr = -1;
+	a->log.head.hash = -1;
+	a->log.head.gen = -1;
+
 	memset(b, 0, sizeof(Blk));
 	b->type = Tlog;
 	b->bp.addr = addr;
--- a/snap.c
+++ b/snap.c
@@ -104,7 +104,36 @@
 	return nil;
 }
 
+int
+snapfreebp(Bptr)
+{
+	return 0;
+}
+
+int
+movedead(Bptr)
+{
+	return 0;
+}
+
 char*
+deletesnap(Tree *s)
+{
+	Tree p;
+	char *e;
+	int i;
+
+	scandead(s->dead[0].head, snapfreebp);
+//	for(i = 1; i < Ndead-1; i++){
+//		if((e = opensnap(&p, s->prev[i])) != nil)
+//			return e;
+//		graftdead(s, s->prev[i], &s->dead[i]);
+//	}
+	scandead(s->dead[Ndead-1].head, movedead);
+	return nil;
+}
+
+char*
 labelsnap(vlong gen, char *name)
 {
 	return modifysnap(gen, name, 0);
@@ -165,88 +194,12 @@
 		putblk(t->dead[Ndead-1].tail);
 	for(i = Ndead-1; i >= 0; i--){
 		t->prev[i] = i == 0 ? gen : t->prev[i-1];
-		t->dead[i].head = -1;
-		t->dead[i].hash = -1;
+		t->dead[i].head.addr = -1;
+		t->dead[i].head.hash = -1;
+		t->dead[i].head.gen = -1;
 		t->dead[i].tail = nil;
 	}
 	*genp = gen;
 	*oldp = t->prev[0];
 	return nil;
-}
-
-int
-sync(void)
-{
-	int i, r;
-	Blk *b, *s;
-	Arena *a;
-
-	qlock(&fs->snaplk);
-	r = 0;
-	s = fs->super;
-	fillsuper(s);
-	enqueue(s);
-
-	for(i = 0; i < fs->narena; i++){
-		a = &fs->arenas[i];
-		finalize(a->log.tail);
-		if(syncblk(a->log.tail) == -1)
-			r = -1;
-	}
-	for(b = fs->chead; b != nil; b = b->cnext){
-		if(!(b->flag & Bdirty))
-			continue;
-		if(syncblk(b) == -1)
-			r = -1;
-	}
-	if(r != -1)
-		r = syncblk(s);
-
-	qunlock(&fs->snaplk);
-	return r;
-}
-
-void
-quiesce(int tid)
-{
-	int i, allquiesced;
-	Bfree *p, *n;
-
-	lock(&fs->activelk);
-	allquiesced = 1;
-	fs->active[tid]++;
-	for(i = 0; i < fs->nproc; i++){
-		/*
-		 * Odd parity on quiescence implies
-		 * that we're between the exit from
-		 * and waiting for the next message
-		 * that enters us into the critical
-		 * section.
-		 */
-		if((fs->active[i] & 1) == 0)
-			continue;
-		if(fs->active[i] == fs->lastactive[i])
-			allquiesced = 0;
-	}
-	if(allquiesced)
-		for(i = 0; i < fs->nproc; i++)
-			fs->lastactive[i] = fs->active[i];
-	unlock(&fs->activelk);
-	if(!allquiesced)
-		return;
-
-	lock(&fs->freelk);
-	p = nil;
-	if(fs->freep != nil){
-		p = fs->freep->next;
-		fs->freep->next = nil;
-	}
-	unlock(&fs->freelk);
-
-	while(p != nil){
-		n = p->next;
-		reclaimblk(p->bp);
-		p = n;
-	}
-	fs->freep = fs->freehd;
 }