shithub: gefs

Download patch

ref: e3f72faa42528a76d3c77081bb0bf11a6ea4efa5
parent: 018c4e07e8d3d32db3325ce331bc34b29d451670
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Nov 3 17:46:17 EDT 2023

fs: clean up old log after syncing for safety

--- a/fs.c
+++ b/fs.c
@@ -2202,7 +2202,7 @@
 {
 	char *e, buf[Offksz];
 	Mount *mnt;
-	Bptr bp, nb;
+	Bptr bp, nb, *oldhd;
 	Arena *a;
 	Amsg *am;
 	vlong off;
@@ -2210,6 +2210,8 @@
 	Msg m;
 	int i;
 
+	if((oldhd = calloc(fs->narena, sizeof(Bptr)) == nil)
+		sysfatal("malloc log heads");
 	while(1){
 		am = chrecv(fs->admchan);
 		switch(am->op){
@@ -2218,10 +2220,11 @@
 				a = &fs->arenas[i];
 				qlock(a);
 				if(a->nlog < a->reserve/(10*Blksz)){
+					oldhd.addr = -1;
 					qunlock(a);
 					continue;
 				}
-				bp = a->loghd;
+				oldhd[i] = a->loghd;
 				epochstart(id);
 				if(compresslog(a) == -1)
 					fprint(2, "compress log: %r");
@@ -2228,8 +2231,20 @@
 				qunlock(a);
 				epochend(id);
 				epochclean();
+			}
 
-				while(bp.addr != -1){
+			qlock(&fs->mutlk);
+			if(am->halt)
+				ainc(&fs->rdonly);
+			epochstart(id);
+			for(mnt = fs->mounts; mnt != nil; mnt = mnt->next)
+				updatesnap(&mnt->root, mnt->root, mnt->name);
+			sync();
+			epochend(id);
+			qunlock(&fs->mutlk);
+
+			for(i = 0; i < fs->narena; i++){
+				for(bp = oldhd[i]; bp.addr != -1; bp = nb){
 					epochstart(id);
 					if((b = getblk(bp, 0)) == nil){
 						fprint(2, "could not load %B\n", bp);
@@ -2244,15 +2259,6 @@
 				}
 			}
 
-			qlock(&fs->mutlk);
-			if(am->halt)
-				ainc(&fs->rdonly);
-			epochstart(id);
-			for(mnt = fs->mounts; mnt != nil; mnt = mnt->next)
-				updatesnap(&mnt->root, mnt->root, mnt->name);
-			sync();
-			epochend(id);
-			qunlock(&fs->mutlk);
 			break;
 		case AOsnap:
 			qlock(&fs->mutlk);