shithub: gefs

Download patch

ref: 0976218b5053b413e631c794b6d4b1918ad4dd78
parent: 6c19bab8acf28d0d70c262ababdc7215850e5c36
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jan 31 21:21:34 EST 2022

blk: fix allocator ordering issues (thanks mcf)

logappend inserts LogAlloc1 in case it needed to
allocate a new log block.

However, these new log blocks are allocated from
the root of the avl tree, and compresslog traverses
starting from avlmin; the current code inserts into
the current log segment, instead of the active one,
which means that logappend could insert a LogAlloc1
for the new log block before the freeing of the block
would be allocated.

Additionally, we chain the wrong block when compressing
the allocation log.

This fixes both issues.

--- a/blk.c
+++ b/blk.c
@@ -24,6 +24,7 @@
 static vlong	blkalloc(int);
 static int	blkdealloc_lk(vlong);
 static Blk*	initblk(vlong, int);
+static int	logop(Arena *, vlong, vlong, int);
 
 static Blk magic;
 
@@ -70,10 +71,10 @@
 	assert(bp != -1);
 	if((b = malloc(sizeof(Blk))) == nil)
 		return nil;
-	off = 0;
+	off = bp;
 	rem = Blksz;
 	while(rem != 0){
-		n = pread(fs->fd, b->buf+off, rem, bp+off);
+		n = pread(fs->fd, b->buf, rem, off);
 		if(n <= 0){
 			free(b);
 			return nil;
@@ -234,7 +235,7 @@
  * recursion.
  */
 static int
-logappend(Arena *_a, vlong off, vlong len, int op, Blk **tl)
+logappend(Arena *a, vlong off, vlong len, int op, Blk **tl)
 {
 	Blk *pb, *lb;
 	vlong o;
@@ -255,7 +256,7 @@
 	 */
 	if(lb == nil || lb->logsz >= Logspc - 40){
 		pb = lb;
-		if((o = blkalloc_lk(_a)) == -1)
+		if((o = blkalloc_lk(a)) == -1)
 			return -1;
 		if((lb = initblk(o, Tlog)) == nil)
 			return -1;
@@ -298,13 +299,16 @@
 	}
 	/*
 	 * The newly allocated log block needs
-	 * to be recorded.
+	 * to be recorded. If we're compressing
+	 * a log, it needs to go to the tail of
+	 * the new log, rather than after the
+	 * current allocation.
+	 *
+	 * Because we've just grown the log, we
+	 * know it won't recurse.
 	 */
-	if(o != -1){
-		p = lb->data + lb->logsz;
-		PBIT64(p, o|LogAlloc1);
-		lb->logsz += 8;
-	}
+	if(o != -1)
+		logop(a, o, Blksz, LogAlloc);
 	/* this gets overwritten by the next append */
 	p = lb->data + lb->logsz;
 	PBIT64(p, (uvlong)LogEnd);
@@ -478,7 +482,7 @@
 		if(logappend(a, log[i].off, log[i].len, LogFree, &tl) == -1)
 			return -1;
 
-	p = b->data + b->logsz;
+	p = tl->data + tl->logsz;
 	PBIT64(p, LogChain|graft);
 	free(log);
 	finalize(b);