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