shithub: riscv

Download patch

ref: 2a622dfcec55ff2b791aa01f12d80ce8ec1225f4
parent: 5a460a150b60697933209f9196cbf9550b50d0eb
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Jan 4 19:11:47 EST 2025

gefs: fix dlist cache limit by maintaining fs->dlcount

--- a/sys/src/cmd/gefs/main.c
+++ b/sys/src/cmd/gefs/main.c
@@ -159,6 +159,8 @@
 		sysfatal("cache too big");
 	if((fs->bcache = mallocz(fs->cmax*sizeof(Bucket), 1)) == nil)
 		sysfatal("malloc: %r");
+
+	fs->dlcount = 0;
 	fs->dlcmax = fs->cmax/10;
 	if(fs->dlcmax < 4)
 		fs->dlcmax = 4;
--- a/sys/src/cmd/gefs/snap.c
+++ b/sys/src/cmd/gefs/snap.c
@@ -16,11 +16,11 @@
 	if(dl->ins == nil)
 		return;
 	traceb("dlflush", dl->ins->bp);
-	enqueue(dl->ins);
-	dropblk(dl->ins);
 	dl->hd = dl->ins->bp;
 	if(dl->tl.addr == dl->hd.addr)
 		dl->tl = dl->hd;
+	enqueue(dl->ins);
+	dropblk(dl->ins);
 	dl->ins = nil;
 	/* special case: the snap dlist has gen -1, skip it */
 	if(dl->gen != -1){
@@ -57,6 +57,7 @@
 		dl->cprev->cnext = dl->cnext;
 	dl->cnext = nil;
 	dl->cprev = nil;
+	fs->dlcount--;
 }
 
 static Dlist*
@@ -130,11 +131,10 @@
 	if(dl->gen == -1)
 		return;
 	dlcachedel(dl, 0);
-	while(fs->dltail != nil && fs->dlcount >= fs->dlcmax){
-		dt = fs->dltail;
-		dlflush(dt);
+	while(fs->dlcount >= fs->dlcmax && (dt = fs->dltail) != nil){
 		dlcachedel(dt, 1);
-		dropblk(dt->ins);
+		dlflush(dt);
+		assert(dt->ins == nil);
 		free(dt);
 	}
 
@@ -145,6 +145,7 @@
 	if(fs->dlhead != nil)
 		fs->dlhead->cprev = dl;
 	fs->dlhead = dl;
+	fs->dlcount++;
 }
 
 void
@@ -267,7 +268,10 @@
 		if(!btnext(&s, &s.kv))
 			break;
 		kv2dlist(&s.kv, &dl);
-
+		if(waserror()){
+			btexit(&s);
+			nexterror();
+		}
 		if(succ != -1 && dl.bgen <= prev)
 			mergedl(succ, dl.gen, dl.bgen);
 		else if(dl.bgen <= prev)
@@ -274,6 +278,7 @@
 			mergedl(prev, dl.gen, dl.bgen);
 		else
 			freedl(&dl, 1);
+		poperror();
 	}
 	btexit(&s);
 	if(succ != -1){
@@ -285,8 +290,14 @@
 			if(!btnext(&s, &s.kv))
 				break;
 			kv2dlist(&s.kv, &dl);
-			if(dl.bgen > prev)
-				freedl(&dl, 1);
+			if(dl.bgen <= prev)
+				continue;
+			if(waserror()){
+				btexit(&s);
+				nexterror();
+			}
+			freedl(&dl, 1);
+			poperror();
 		}
 		btexit(&s);
 	}
--