shithub: gefs

Download patch

ref: 8ad21d99f5b7db36769ac57d265f2f1c5bacd37c
parent: 65978672633bc578659cc95128f5ce3a20828b33
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Dec 10 17:07:11 EST 2023

fs: skip adm messages when fs is readonly

small but harmless race -- we may flip rdonly while
enqueueing a message, which may lead to a spurious
message print.

--- a/fs.c
+++ b/fs.c
@@ -2207,6 +2207,10 @@
 		sysfatal("malloc log heads");
 	while(1){
 		am = chrecv(fs->admchan);
+		if(fs->rdonly){
+			fprint(2, "spurious adm message\n");
+			break;
+		}
 		switch(am->op){
 		case AOsync:
 			if(waserror()){
@@ -2291,6 +2295,7 @@
 			if(waserror()){
 				fprint(2, "clear file %llx: %s\n", am->qpath, errmsg());
 				ainc(&fs->rdonly);
+				break;
 			}
 			for(off = am->off; off < am->length; off += Blksz){
 				qlock(&fs->mutlk);
@@ -2357,9 +2362,11 @@
 	tmnow(&then, nil);
 	tmnow(&now, nil);
 	while(1){
+		sleep(5000);
+		if(fs->rdonly)
+			continue;
 		if(waserror())
 			fprint(2, "task error: %s", errmsg());
-		sleep(5000);
 		a = emalloc(sizeof(Amsg), 1);
 		a->op = AOsync;
 		a->halt = 0;
--- a/load.c
+++ b/load.c
@@ -64,7 +64,9 @@
 	Arena *a;
 	Bptr bp;
 	Tree *t;
+	Dir *d;
 	int i, k;
+	vlong eb;
 
 	if((dump = mallocz(sizeof(*dump), 1)) == nil)
 		sysfatal("malloc: %r");
@@ -80,10 +82,16 @@
 	fs->narena = 1;
 	if((fs->fd = open(dev, ORDWR)) == -1)
 		sysfatal("open %s: %r", dev);
+	if((d = dirfstat(fs->fd)) == nil)
+		sysfatal("stat %s: %r", dev);
+
+	eb = d->length - (d->length%Blksz) - Blksz;
 	bp = (Bptr){0, -1, -1};
 	fs->sb0 = getblk(bp, GBnochk);
-	bp = (Bptr){512*MiB, -1, -1};
+	bp = (Bptr){eb, -1, -1};
 	fs->sb1 = getblk(bp, GBnochk);
+	free(d);
+
 	unpacksb(fs, fs->sb0->buf, Blksz);
 	if((fs->arenas = calloc(fs->narena, sizeof(Arena))) == nil)
 		sysfatal("malloc: %r");
--- a/ream.c
+++ b/ream.c
@@ -168,10 +168,6 @@
 	Blk *b, *hd, *tl;
 
 	b = cachepluck();
-	if(start == 512*MiB){
-		start += Blksz;
-		asz -= Blksz;
-	}
 	addr = start+Blksz;	/* leave room for arena hdr */
 
 	a->loghd.addr = -1;
@@ -181,10 +177,6 @@
 	memset(b->buf, 0, sizeof(b->buf));
 	b->type = Tlog;
 	b->bp.addr = addr+Blksz;
-	if(b->bp.addr == 512*MiB){
-		b->bp.addr += Blksz;
-		asz -= Blksz;
-	}
 	b->logsz = 0;
 	b->logp = (Bptr){-1, -1, -1};
 	b->data = b->buf + Loghdsz;
@@ -196,11 +188,6 @@
 	PACK64(p, asz-Blksz);		p += 8;	/* len */
 	PACK64(p, b->bp.addr|LogAlloc);	p += 8;	/* addr */
 	PACK64(p, Blksz);		p += 8;	/* len */
-	/* backup sb */
-	if(start <= 512*MiB && start+asz > 512*MiB){
-		PACK64(p, (512*MiB)|LogAlloc1);
-		p += 8;
-	}
 	PACK64(p, (uvlong)LogSync);	p += 8;	/* barrier */
 	b->logsz = p - b->data;
 	finalize(b);
@@ -261,8 +248,6 @@
 	sz = d->length;
 	free(d);
 
-	if(sz < 512*MiB+Blksz)
-		sysfatal("ream: disk too small");
 	mnt = emalloc(sizeof(Mount), 1);
 	mnt->root = mallocz(sizeof(Tree), 1);
 	adm = mallocz(sizeof(Mount), 1);
@@ -286,7 +271,7 @@
 	sb0 = cachepluck();
 	sb1 = cachepluck();
 	sb0->bp = (Bptr){0, -1, -1};
-	sb1->bp = (Bptr){512*MiB, -1, -1};
+	sb1->bp = (Bptr){sz+Blksz, -1, -1};
 
 	fs->arenabp = emalloc(fs->narena * sizeof(Bptr), 1);
 	for(i = 0; i < fs->narena; i++){