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