shithub: gefs

Download patch

ref: 383a92cb9963a04aea7b0c31048a7bb1eabb9476
parent: a742b7cb40538d0bdd5d4420a3478f7c7d60f157
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jul 19 01:24:29 EDT 2022

quiesce: fix race

if the writer deferred frees between the quiesce and grabbing/trimming
the freelist, we could free blocks from the next epoch, which would
be bad.

--- a/blk.c
+++ b/blk.c
@@ -902,22 +902,21 @@
 		if(fs->active[i] == fs->lastactive[i])
 			allquiesced = 0;
 	}
-	if(allquiesced)
+	p = nil;
+	if(allquiesced){
+		inc64(&fs->qgen, 1);
 		for(i = 0; i < fs->nquiesce; i++)
 			fs->lastactive[i] = fs->active[i];
-	unlock(&fs->activelk);
-	if(!allquiesced)
-		return;
 
-	inc64(&fs->qgen, 1);
-	lock(&fs->freelk);
-	p = nil;
-	if(fs->freep != nil){
-		p = fs->freep->next;
-		fs->freep->next = nil;
+		lock(&fs->freelk);
+		if(fs->freep != nil){
+			p = fs->freep->next;
+			fs->freep->next = nil;
+		}
+		fs->freep = fs->freehd;
+		unlock(&fs->freelk);
 	}
-	fs->freep = fs->freehd;
-	unlock(&fs->freelk);
+	unlock(&fs->activelk);
 
 	while(p != nil){
 		n = p->next;