shithub: gefs

Download patch

ref: 8a9740a385460c91c2791182170b78980d417bd8
parent: 73995a559cd5864886100e5a225db0a58638790b
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Dec 10 15:46:51 EST 2023

check: scan deadlists and free log too

--- a/check.c
+++ b/check.c
@@ -24,7 +24,7 @@
 }
 
 static int
-badtree(int fd, Blk *b, int h, Kvp *lo, Kvp *hi)
+checktree(int fd, Blk *b, int h, Kvp *lo, Kvp *hi)
 {
 	Kvp x, y;
 	Msg mx, my;
@@ -78,7 +78,7 @@
 				fprint(fd, "mismatched block fill\n");
 				fail++;
 			}
-			if(badtree(fd, c, h - 1, &x, &y))
+			if(checktree(fd, c, h - 1, &x, &y))
 				fail++;
 			dropblk(c);
 		}
@@ -104,7 +104,7 @@
 			fprint(fd, "corrupt block: %B\n", bp);
 			fail++;
 		}
-		if(c != nil && badtree(fd, c, h - 1, &y, nil))
+		if(c != nil && checktree(fd, c, h - 1, &y, nil))
 			fail++;
 		dropblk(c);
 	}
@@ -149,8 +149,28 @@
 }
 
 static int
-badfree(void)
+checklog(int fd, Bptr hd)
 {
+	Bptr bp, nb;
+	Blk *b;
+
+	bp = (Bptr){-1, -1, -1};
+	for(bp = hd; bp.addr != -1; bp = nb){
+		if(waserror()){
+			fprint(fd, "error loading %B\n", bp);
+			return 0;
+		}
+		b = getblk(bp, 0);
+		nb = b->logp;
+		dropblk(b);
+		poperror();
+	}
+	return 1;
+}
+
+static int
+checkfree(int fd)
+{
 	Arange *r, *n;
 	int i, fail;
 
@@ -170,9 +190,34 @@
 			r = n;
 		}
 	}
+	for(i = 0; i < fs->narena; i++)
+		if(!checklog(fd, fs->arenas[i].loghd))
+			fprint(fd, "arena %d: broken freelist\n", i);
 	return fail;
 }
 
+static int
+checkdlist(int fd)
+{
+	char pfx[1];
+	Dlist dl;
+	Scan s;
+
+	checklog(fd, fs->snapdl.hd);
+	pfx[0] = Kdlist;
+	btnewscan(&s, pfx, 1);
+	btenter(&fs->snap, &s);
+	while(1){
+		if(!btnext(&s, &s.kv))
+			break;
+		kv2dlist(&s.kv, &dl);
+		if(!checklog(fd, dl.hd))
+			print("bad dlist %P: %s\n", &s.kv, errmsg());
+	}
+	btexit(&s);
+	return 0;
+}
+
 int
 checkfs(int fd)
 {
@@ -190,11 +235,14 @@
 		return 0;
 	}
 	fprint(fd, "checking freelist\n");
-	if(badfree())
+	if(checkfree(fd))
 		ok = 0;
+	fprint(fd, "checking deadlist\n");
+	if(checkdlist(fd))
+		ok = 0;
 	fprint(fd, "checking snap tree: %B\n", fs->snap.bp);
 	if((b = getroot(&fs->snap, &height)) != nil){
-		if(badtree(fd, b, height-1, nil, 0))
+		if(checktree(fd, b, height-1, nil, 0))
 			ok = 0;
 		dropblk(b);
 	}
@@ -217,7 +265,7 @@
 		}
 		fprint(fd, "checking snap %s: %B\n", name, t->bp);
 		b = getroot(t, &height);
-		if(badtree(fd, b, height-1, nil, 0))
+		if(checktree(fd, b, height-1, nil, 0))
 			ok = 0;
 		dropblk(b);
 		poperror();