shithub: gefs

Download patch

ref: 4b6deb085f97251e0d57936db726b0f9fd8c5512
parent: 8a0a5128be9870261845756ad9b924a613829f7b
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Apr 7 12:48:47 EDT 2023

log: compress it live

--- a/blk.c
+++ b/blk.c
@@ -290,6 +290,7 @@
 			dropblk(pb);
 		}
 		*tl = lb;
+		a->nlog++;
 	}
 
 	if(len == Blksz){
@@ -538,6 +539,9 @@
 			unlock(a);
 		}
 	}
+	lock(a);
+	a->nlog = 0;
+	unlock(a);
 	finalize(a->tail);
 	if(syncblk(a->tail) == -1)
 		return -1;
--- a/dat.h
+++ b/dat.h
@@ -514,9 +514,10 @@
 	vlong	size;
 	vlong	used;
 	vlong	reserve;
-	/* freelist */
-	Bptr	head;
-	Blk	*tail;	/* tail held open for writing */
+	/* allocation log */
+	vlong	nlog;	/* number of blocks logged since last compression */
+	Bptr	head;	/* start of allocation log */
+	Blk	*tail;	/* end of the log, open for writing */
 	Syncq	*sync;
 };
 
--- a/fs.c
+++ b/fs.c
@@ -2125,6 +2125,7 @@
 void
 runtasks(int, void *)
 {
+	int i, c;
 	Fmsg *m;
 	Amsg *a;
 
@@ -2142,6 +2143,25 @@
 		a->halt = 0;
 		a->fd = -1;
 		m->a = a;
-		chsend(fs->wrchan, m);	
+		chsend(fs->wrchan, m);
+
+		/*
+		 * compresslog is designed to be concurrent with allocation,
+		 * so it's safe to call from outside the mutator proc; we
+		 * don't want to spend a ton of time compressing, though,
+		 * so we only do the compression when our log gets big.
+		 *
+		 * 1/4 of our reserved emergency space seems like a good
+		 * heuristic for big, but it was picked arbitrarily.
+		 */
+		for(i = 0; i < fs->narena; i++){
+			lock(&fs->arenas[i]);
+			c = fs->arenas[i].nlog > fs->arenas[i].reserve/(4*Blksz);
+			unlock(&fs->arenas[i]);
+			if(c){
+				if(compresslog(&fs->arenas[i]) == -1)
+					fprint(2, "compress log: %r");
+			}
+		}
 	}
 }