shithub: gefs

Download patch

ref: bf1741f8242dc7040e8ee66f4f8c6a1dad7018a4
parent: 7a48c9dfd74af47145a4a2a884ae3e0e2793453a
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Dec 17 15:57:06 EST 2023

blk: async sync

allow enqueuing new writes while we wait for the blocks
in queue to hit disk, so that our write throughput doesn't
drop dramatically when syncing.

--- a/blk.c
+++ b/blk.c
@@ -482,7 +482,7 @@
 }
 
 int
-syncbarrier(Arena *a, vlong gen)
+logbarrier(Arena *a, vlong gen)
 {
 	logappend(a, gen<<8, 0, LogSync);
 	if(a->loghd.addr == -1)
@@ -1076,12 +1076,33 @@
 	}
 }
 
+vlong
+wrbarrier(void)
+{
+	Qent qe;
+	vlong gen;
+	int i;
+	
+	gen = aincv(&fs->qgen, 1);
+	fs->syncing = fs->nsyncers;
+	for(i = 0; i < fs->nsyncers; i++){
+		qe.op = Qfence;
+		qe.bp.addr = 0;
+		qe.bp.hash = -1;
+		qe.bp.gen = -1;
+		qe.b = nil;
+		qput(&fs->syncq[i], qe);
+	}
+	while(fs->syncing != 0)
+		rsleep(&fs->syncrz);
+	return gen;
+}
+
 void
 sync(void)
 {
 	uvlong gen;
 	Arena *a;
-	Qent qe;
 	int i;
 
 
@@ -1098,25 +1119,14 @@
 		nexterror();
 	}
 	flushdlcache(1);
-	gen = aincv(&fs->qgen, 1);
-	fs->syncing = fs->nsyncers;
-	for(i = 0; i < fs->nsyncers; i++){
-		qe.op = Qfence;
-		qe.bp.addr = 0;
-		qe.bp.hash = -1;
-		qe.bp.gen = -1;
-		qe.b = nil;
-		qput(&fs->syncq[i], qe);
-	}
-	while(fs->syncing != 0)
-		rsleep(&fs->syncrz);
+	gen = wrbarrier();
 	/* pass 0: sync arena contents */
 	for(i = 0; i < fs->narena; i++){
 		a = &fs->arenas[i];
 		qlock(a);
-		syncbarrier(a, gen);
-		finalize(a->logtl);
-		syncblk(a->logtl);
+		logbarrier(a, gen);
+		setflag(a->logtl, Bdirty);
+		enqueue(a->logtl);
 		qunlock(a);
 	}
 	/*
@@ -1128,10 +1138,11 @@
 		a = &fs->arenas[i];
 		qlock(a);
 		packarena(a->h0->data, Blksz, a);
-		finalize(a->h0);
-		syncblk(a->h0);
+		setflag(a->h0, Bdirty);
+		enqueue(a->h0);
 		qunlock(a);
 	}
+	wrbarrier();
 	/*
 	 * pass 2: sync superblock; we have a consistent
 	 * set of block headers, so if we crash, we can
@@ -1157,8 +1168,8 @@
 		a = &fs->arenas[i];
 		qlock(a);
 		packarena(a->h1->data, Blksz, a);
-		finalize(a->h1);
-		syncblk(a->h1);
+		setflag(a->h1, Bdirty);
+		enqueue(a->h1);
 		qunlock(a);
 	}
 	/*
--- a/fs.c
+++ b/fs.c
@@ -2256,10 +2256,10 @@
 			for(mnt = fs->mounts; mnt != nil; mnt = mnt->next)
 				updatesnap(&mnt->root, mnt->root, mnt->name);
 			unlock(&fs->mountlk);
-			sync();
+			qunlock(&fs->mutlk);
 			epochend(id);
 			epochclean();
-			qunlock(&fs->mutlk);
+			sync();
 
 			for(i = 0; i < fs->narena; i++){
 				for(bp = oldhd[i]; bp.addr != -1; bp = nb){