ref: d5122d1bcd61d4112f14dbbf3180e732f196ad63
parent: cd0d5bf94d91d31b5b9768551010a4453459fdf9
author: Ori Bernstein <[email protected]>
date: Sat May 27 20:55:02 EDT 2023
blk: return block load errors to caller, fix sync ordering when we sync arenas, we need to sync the headers, then sync the superblock, and then sync the footers; that means that we have at least one consistent set of blocks: If we crash while syncing the headers, the footers are consistent. If we crash while syncing the main superblock, then the backup superblock points at the footers, which are consistent. If we crash while syncing the backup superblock, the main superblock points at the headers, which are consistent. If we crash while writing hte footers, the headers and superblocks are consistent.
--- a/blk.c
+++ b/blk.c
@@ -837,7 +837,6 @@
}
if((b = readblk(bp.addr, flg)) == nil){
qunlock(&fs->blklk[i]);
- abort();
return nil;
}
b->alloced = getcallerpc(&bp);
@@ -845,7 +844,6 @@
if((flg&GBnochk) == 0 && h != bp.hash){
fprint(2, "corrupt block %p %B: %.16llux != %.16llux\n", b, bp, h, bp.hash);
qunlock(&fs->blklk[i]);
- abort();
return nil;
}
b->bp.hash = h;
@@ -1153,7 +1151,25 @@
unlock(a);
}
/*
- * pass 2: sync block footers; if we crash here,
+ * pass 2: sync superblock; we have a consistent
+ * set of block headers, so if we crash, we can
+ * use the loaded block headers; the footers will
+ * get synced after so that we can use them next
+ * time around.
+ */
+ for(i = 0; i < fs->narena; i++)
+ fs->arenabp[i] = fs->arenas[i].hd->bp;
+ packsb(fs->sb0->buf, Blksz, fs);
+ packsb(fs->sb1->buf, Blksz, fs);
+ finalize(fs->sb0);
+ finalize(fs->sb1);
+ if(syncblk(fs->sb0) == -1)
+ sysfatal("sync sb: %r");
+ if(syncblk(fs->sb1) == -1)
+ sysfatal("sync sb: %r");
+
+ /*
+ * pass 3: sync block footers; if we crash here,
* the block headers are consistent, and we can
* use them.
*/
@@ -1166,16 +1182,5 @@
sysfatal("sync arena: %r");
unlock(a);
}
- for(i = 0; i < fs->narena; i++)
- fs->arenabp[i] = fs->arenas[i].hd->bp;
-
- packsb(fs->sb0->buf, Blksz, fs);
- packsb(fs->sb1->buf, Blksz, fs);
- finalize(fs->sb0);
- finalize(fs->sb1);
- if(syncblk(fs->sb0) == -1)
- sysfatal("sync sb: %r");
- if(syncblk(fs->sb1) == -1)
- sysfatal("sync sb: %r");
qunlock(&fs->synclk);
}