shithub: gefs

Download patch

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);
 }