git: 9front

Download patch

ref: 2d6526b1a8b6b155c7e4b76efad124cbdd8d3c42
parent: 97b5e4719c3034cfd5086130adef433769e0586b
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Nov 21 23:24:24 EST 2025

gefs: truncate the log after the last sync barrier

Anything after the last sync barrier didn't happen,
including the allocation of the trailing log blocks,
so we should just ignore it to prevent possible
double frees.

When syncing the file system, we queue a sync to
the log, take a snapshot of the root, and allow
appending, so our allocation log ends up looking
something like:

	[ops][sync N][ops...)

When we load the FS, we should skip the allocs
and frees done on the unsyned tree, so we only
replay up to

	[ops][sync N]

But, if we have trailing log blocks, and we decide
to compress the log before we clober the link to
the rest of the trailing ops, we'll try to free
all of the trailing log blocks that didn't happen,
and will fail with a double free.

So, let's not do that.

--- a/sys/src/cmd/gefs/blk.c
+++ b/sys/src/cmd/gefs/blk.c
@@ -359,6 +359,7 @@
 				dprint("\tlog@%x: sync %lld\n", i, gen);
 				if(gen >= agetv(&fs->qgen)){
 					if(a->logtl == nil){
+						b->logp = Zb;
 						b->logsz = i;
 						a->logtl = b;
 						cachedel(b->bp.addr);
--