shithub: gefs

Download patch

ref: 0c6f17f8c8e759c15cf94de01d2e754978334b96
parent: 55b15443d3f318a3c488d760763cb3e232cacdd9
author: glenda <glenda@9front.local>
date: Wed Dec 15 18:46:57 EST 2021

blk: refactor allocation log to list

This prepares for appending to deadlists.

--- a/blk.c
+++ b/blk.c
@@ -13,6 +13,7 @@
 };
 
 static vlong	blkalloc_lk(Arena*);
+static vlong	blkalloc(void);
 static int	blkdealloc_lk(vlong);
 static void	cachedel(vlong);
 
@@ -75,17 +76,11 @@
 }
 
 static Arena*
-pickarena(vlong hint)
+pickarena(void)
 {
 	long n;
 
-	n = -1; /* shut up, ken */
-	if(hint > 0 || hint < fs->narena)
-		n = hint / fs->arenasz;
-	else if(hint == -1)
-		n = ainc(&fs->nextarena) % fs->narena;
-	else
-		abort();
+	n = (ainc(&fs->roundrobin)/1024) % fs->narena;
 	return &fs->arenas[n];
 }
 
@@ -174,17 +169,22 @@
 }
 
 Blk*
-logappend(Arena *a, Blk *lb, vlong off, vlong len, int op)
+logappend(Oplog *ol, Arena *a, vlong off, vlong len, int op)
 {
-	Blk *pb;
+	Blk *pb, *lb;
 	vlong o;
 	char *p;
 
 	assert(off % Blksz == 0);
 	assert(op == LogAlloc || op == LogFree);
+	lb = ol->tail;
 	if(lb == nil || lb->logsz > Logspc - 8){
 		pb = lb;
-		if((o = blkalloc_lk(a)) == -1)
+		if(a == nil)
+			o = blkalloc();
+		else
+			o = blkalloc_lk(a);
+		if(o == -1)
 			return nil;
 		if((lb = mallocz(sizeof(Blk), 1)) == nil)
 			return nil;
@@ -201,7 +201,7 @@
 			return nil;
 		}
 
-		a->logtl = lb;
+		ol->tail = lb;
 		if(pb != nil){
 			p = pb->data + pb->logsz;
 			PBIT64(p + 0, lb->bp.addr|LogChain);
@@ -239,12 +239,12 @@
 {
 	Blk *b;
 
-	if((b = logappend(a, a->logtl, off, Blksz, op)) == nil)
+	if((b = logappend(&a->log, a, off, Blksz, op)) == nil)
 		return -1;
-	if(a->log == -1)
-		a->log = b->bp.addr;
-	if(b != a->logtl)
-		a->logtl = b;
+	if(a->log.head == -1)
+		a->log.head = b->bp.addr;
+	if(b != a->log.tail)
+		a->log.tail = b;
 	return 0;
 }
 
@@ -258,7 +258,7 @@
 	int op, i, n;
 
 
-	bp = a->log;
+	bp = a->log.head;
 
 Nextblk:
 	if((b = readblk(bp, 0)) == nil)
@@ -329,6 +329,7 @@
 	vlong v, bp, nb, graft, oldhd;
 	int i, n, sz;
 	Blk *hd, *ab, *b;
+	Oplog ol;
 	char *p;
 
 	/*
@@ -362,14 +363,14 @@
 	}
 
 	graft = b->bp.addr;
-	if(a->logtl != nil){
-		finalize(a->logtl);
-		if(syncblk(a->logtl) == -1){
+	if(a->log.tail != nil){
+		finalize(a->log.tail);
+		if(syncblk(a->log.tail) == -1){
 			free(b);
 			return -1;
 		}
 	}
-	a->logtl = b;
+	a->log.tail = b;
 
 	/*
 	 * Prepare what we're writing back.
@@ -399,9 +400,12 @@
 		return -1;
 	}
 	hd = b;
+	ol.hash = -1;
+	ol.head = b->bp.addr;
+	ol.tail = b;
 	b->logsz = Loghdsz;
 	for(i = 0; i < n; i++)
-		if((b = logappend(a, b, log[i].off, log[i].len, LogFree)) == nil)
+		if((b = logappend(&ol, a, log[i].off, log[i].len, LogFree)) == nil)
 			return -1;
 	p = b->data + b->logsz;
 	PBIT64(p, LogChain|graft);
@@ -410,12 +414,12 @@
 	if(syncblk(b) == -1)
 		return -1;
 
-	oldhd = a->log;
-	a->log = hd->bp.addr;
-	a->logh = blkhash(hd);
+	oldhd = a->log.head;
+	a->log.head = hd->bp.addr;
+	a->log.hash = blkhash(hd);
 	ab = a->b;
-	PBIT64(ab->data + 0, a->log);
-	PBIT64(ab->data + 8, a->logh);
+	PBIT64(ab->data + 0, a->log.head);
+	PBIT64(ab->data + 8, a->log.hash);
 	finalize(ab);
 	if(syncblk(ab) == -1)
 		return -1;
@@ -444,8 +448,8 @@
 			unlock(a);
 		}
 	}
-	finalize(a->logtl);
-	if(syncblk(a->logtl) == -1)
+	finalize(a->log.tail);
+	if(syncblk(a->log.tail) == -1)
 		return -1;
 	return 0;
 }
@@ -502,8 +506,8 @@
 	return r;
 }
 
-vlong
-blkalloc(vlong hint)
+static vlong
+blkalloc(void)
 {
 	Arena *a;
 	vlong b;
@@ -511,12 +515,11 @@
 
 	tries = 0;
 Again:
-	a = pickarena(hint);
+	a = pickarena();
 	if(a == nil || tries == fs->narena){
 		werrstr("no empty arenas");
 		return -1;
 	}
-	lock(a);
 	/*
 	 * TODO: there's an extreme edge case
 	 * here.
@@ -530,6 +533,7 @@
 	 * correctly.
 	 */
 	tries++;
+	lock(a);
 	if((b = blkalloc_lk(a)) == -1){
 		unlock(a);
 		goto Again;
@@ -548,7 +552,7 @@
 	Blk *b;
 	vlong bp;
 
-	if((bp = blkalloc(-1)) == -1)
+	if((bp = blkalloc()) == -1)
 		return nil;
 	if((b = lookupblk(bp)) == nil){
 		if((b = mallocz(sizeof(Blk), 1)) == nil)
--- a/dat.h
+++ b/dat.h
@@ -18,6 +18,7 @@
 typedef struct Bucket	Bucket;
 typedef struct Chan	Chan;
 typedef struct Tree	Tree;
+typedef struct Oplog	Oplog;
 typedef struct Mount	Mount;
 
 enum {
@@ -347,7 +348,7 @@
 
 	Arena	*arenas;
 	int	narena;
-	long	nextarena;
+	long	roundrobin;
 	vlong	arenasz;
 
 	Lock	fidtablk;
@@ -364,18 +365,20 @@
 	int	cmax;
 };
 
+struct Oplog {
+	vlong	head;	/* log head */
+	vlong	hash;	/* log head hash */
+	Blk	*tail;	/* tail block open for writing */
+};
+
 struct Arena {
 	Lock;
 	Avltree *free;
 	Avltree *partial;
-
-	vlong	log;	/* log head */
-	vlong	logh;	/* log head hash */
-	Blk	*logtl;	/* tail block open for writing */
 	Blk	*b;	/* arena block */
-
 	Blk	**q;	/* write queue */
 	vlong	nq;
+	Oplog	log;
 };
 
 struct Key{
--- a/load.c
+++ b/load.c
@@ -22,8 +22,8 @@
 	if((b = readblk(o, 0)) == nil)
 		return -1;
 	a->b = b;
-	a->log = GBIT64(b->data+0);
-	a->logh = GBIT64(b->data+8);
+	a->log.head = GBIT64(b->data+0);
+	a->log.hash = GBIT64(b->data+8);
 	if(loadlog(a) == -1)
 		return -1;
 	if(compresslog(a) == -1)
--- a/ream.c
+++ b/ream.c
@@ -83,7 +83,7 @@
 		sysfatal("ream: %r");
 	addr += Blksz;	/* arena header */
 
-	a->log = -1;
+	a->log.head = -1;
 	memset(b, 0, sizeof(Blk));
 	b->type = Tlog;
 	b->bp.addr = addr;
--- a/sync.c
+++ b/sync.c
@@ -136,8 +136,8 @@
 
 	for(i = 0; i < fs->narena; i++){
 		a = &fs->arenas[i];
-		finalize(a->logtl);
-		if(syncblk(a->logtl) == -1)
+		finalize(a->log.tail);
+		if(syncblk(a->log.tail) == -1)
 			r = -1;
 	}
 	for(b = fs->chead; b != nil; b = b->cnext){