git: 9front

Download patch

ref: 9557847cfe71ebfa4e5ffdf5c80fe5beccfc38bd
parent: 096772cab785a26f3c8e30aa14befac8e28c5a4f
author: Ori Bernstein <ori@eigenstate.org>
date: Sun May 26 18:01:41 EDT 2024

gefs: avoid holding the wrlock when syncing the file system

we only need to enforce ordering or syncedness to disk when
writing out the blocks during sync, we don't need to prevent
mutation on the tree once the arenas and superblock are
serialized.

--- a/sys/src/cmd/gefs/blk.c
+++ b/sys/src/cmd/gefs/blk.c
@@ -153,8 +153,10 @@
 
 	lo = 0;
 	hi = fs->narena;
-	if(b == 0)
+	if(b == fs->sb0->bp.addr)
 		return &fs->arenas[0];
+	if(b == fs->sb1->bp.addr)
+		return &fs->arenas[hi-1];
 	while(1){
 		mid = (hi + lo)/2;
 		a = &fs->arenas[mid];
@@ -1000,7 +1002,7 @@
 	int i;
 
 	if(qe.op == Qfree || qe.op == Qwrite)
-		assert(qe.bp.addr != 0 && (qe.bp.addr & (Blksz-1)) == 0);
+		assert((qe.bp.addr & (Blksz-1)) == 0);
 	else if(qe.op == Qfence)
 		assert(fs->syncing > 0);
 	else
--- a/sys/src/cmd/gefs/fs.c
+++ b/sys/src/cmd/gefs/fs.c
@@ -38,11 +38,18 @@
 static void
 wrbarrier(void)
 {
+	tracev("barrier", fs->qgen);
+	aincv(&fs->qgen, 1);
+}
+
+static void
+wrwait(void)
+{
 	Qent qe;
 	int i;
-	
+
+	tracev("wrwait", fs->qgen);
 	aincv(&fs->qgen, 1);
-	tracev("barrier", fs->qgen);
 	fs->syncing = fs->nsyncers;
 	for(i = 0; i < fs->nsyncers; i++){
 		qe.op = Qfence;
@@ -130,6 +137,8 @@
 	packsb(fs->sb1->buf, Blksz, fs);
 	finalize(fs->sb0);
 	finalize(fs->sb1);
+	setflag(fs->sb0, Bdirty);
+	setflag(fs->sb1, Bdirty);
 	fs->snap.dirty = 0;
 	qunlock(&fs->mutlk);
 
@@ -150,10 +159,10 @@
 	 * get synced after so that we can use them next
 	 * time around.
          */
-	qlock(&fs->mutlk);
 	tracem("supers");
-	syncblk(fs->sb0);
-	syncblk(fs->sb1);
+	enqueue(fs->sb0);
+	enqueue(fs->sb1);
+	wrbarrier();
 
 	/*
 	 * pass 3: sync block footers; if we crash here,
@@ -165,11 +174,13 @@
 		enqueue(fs->arenas[i].h1);
 
 	/*
-	 * Pass 4: clean up the old snap tree's deadlist
+	 * Pass 4: clean up the old snap tree's deadlist.
+	 * we need to wait for all the new data to hit disk
+	 * before we can free anything, otherwise it gets
+	 * clobbered.
 	 */
 	tracem("snapdl");
-	wrbarrier();
-	qunlock(&fs->mutlk);
+	wrwait();
 	freedl(&dl, 1);
 	qunlock(&fs->synclk);
 	tracem("synced");
--