code: mafs

Download patch

ref: 4d4140d98d6869142a2e5bdb60e42596552afe7b
parent: e304f2e6605238ee707398d0210f13d739e0395f
author: 9ferno <gophone2015@gmail.com>
date: Fri Nov 25 11:20:43 EST 2022

fix the sync deadlock when out of extents

--- a/ctl.c
+++ b/ctl.c
@@ -22,7 +22,7 @@
 
 	while((n=sync()) > 0){
 		// if(chatty9p > 1)
-		dprint("shutdown: sync() finds %llud locked blocks\n", n);
+		dprint("sync(): finds %llud locked blocks\n", n);
 		sleep(1000);
 	}
 	return 0;
--- a/extents.c
+++ b/extents.c
@@ -443,40 +443,40 @@
 }
 
 /* allocate n blocks and return that block number */
-s8
-balloc(Extents *es, u64 n, u64 *start)
+u64
+balloc(Extents *es, u64 n)
 {
 	Extent *e;
+	u64 start;
 	char msg[64];
-	s8 rv;
 
 	if(es == nil)
 		panic("balloc: es == nil");
-	*start = 0;
+	start = 0;
+	USED(start);
 	qlock(&es->lck);
-	if(es->n == 0){
-		// rsleep(&es->isempty);
-		rv = -1;
-		goto ballocend;
-	}
-	if(chatty9p > 7){
+	if(es->n == 0)
+		rsleep(&es->isempty);
+/*	if(chatty9p > 7){
 		snprint(msg, 64, "balloc() %llud blocks:\n", n);
 		showextents(2, msg, es);
-	}
+	}*/
+again:
 	for(e = lowest(es); e != nil && e->len < n; e = e->high)
 		;
 	if(e == nil){
-		rv = -1;
-		goto ballocend;
+		snprint(msg, 64, "balloc() %llud %s: waiting\n", n, es->name);
+		showextents(2, msg, es);
+		rsleep(&es->isempty);
+		goto again;
 	}
 	else if(e->len == n)
-		*start = pluck(es, e);
+		start = pluck(es, e);
 	else /* found something bigger */
-		*start = slice(es, e, n);
-	rv = 1;
-ballocend:
+		start = slice(es, e, n);
+
 	qunlock(&es->lck);
-	return rv;
+	return start;
 }
 
 /* reallocate n blocks to nnew blocks and return that block number
@@ -485,7 +485,6 @@
    Not providing brealloc() as we would need access to the contents
    to copy stuff over.
  */
-
 /* free n blocks allocated at block number */
 void
 bfree(Extents *es, u64 start, u64 len)
@@ -496,7 +495,7 @@
 		panic("bfree: len <= 0");
 	qlock(&es->lck);
 	add(es, start, len);
-	if(es->n == 1)
+//	if(es->n == 1) the sleeper could just be waiting for a different len block
 		rwakeup(&es->isempty);
 	qunlock(&es->lck);
 }
@@ -682,9 +681,11 @@
 }
 
 void
-initextents(Extents *es)
+initextents(Extents *es, char *name)
 {
 	es->isempty.l = &es->lck;
+	if(name != nil)
+		strncpy(es->name, name, 32);
 }
 
 /* obsolete */
--- a/extents.h
+++ b/extents.h
@@ -27,6 +27,7 @@
 
 	u8 nlru;		/* number of items in the lru linked list */
 	Extent *lru;	/* least recently used extent in the circular lru linked list */
+	char name[32];
 };
 
 extern int chatty9p;
@@ -42,9 +43,9 @@
 s32	saveextents(Extents *es, s8 *buf, u32 nbuf);
 s32	loadextents(Extents *es, s8 *buf, u32 nbuf);
 
-s8	 balloc(Extents *es, u64 len, u64 *start);
+u64	 balloc(Extents *es, u64 len);
 void bfree(Extents *es, u64 blkno, u64 len);
 u64	 nfrees(Extents *es);
 
 Extent *lowest(Extents *es);
-void	initextents(Extents *es);
+void	initextents(Extents *es, char *name);
--- a/free.c
+++ b/free.c
@@ -50,7 +50,7 @@
 		print("%s %llud bytes %llud blocks\n", devfile, size, size/Blocksize);
 
 	checkdentry(Bdfrees, Tdentry, Qpfrees);
-	initextents(&frees);
+	initextents(&frees, "frees");
 	getfrees(Bdfrees);
 	showextents(1, "", &frees);
 	// showblocknos(1, &frees);
--- a/iobuf.c
+++ b/iobuf.c
@@ -20,7 +20,7 @@
 {
 	memunitstart = sbrk((nunits+1) * Blocksize);
 	memunitpool = memunitstart+Blocksize- ((u64)memunitstart%Blocksize);
-	initextents(&memunits);
+	initextents(&memunits, "memunits");
 	if(chatty9p > 4)
 		dprint("initmemunitpool: memunitpool %p nunits*Blocksize %p\n",
 				memunitpool, nunits*Blocksize);
@@ -35,19 +35,8 @@
 {
 	u64 m;
 	u8 *a;
-	u8 repeat;
-	s8 st;
 
-	st = -1;
-	for(repeat = 0;
-		repeat < 10 && (st = balloc(&memunits, len, &m)) < 0;
-		repeat++){
-		showextents(2, "out of memunits: ", &memunits);
-		if(sync()==0)
-			repeat = 9;
-	}
-	if(st < 0)
-		panic("out of memory\n");
+	m = balloc(&memunits, len);
 	if(chatty9p > 4)
 		dprint("allocmemunit: memunitpool %p m %p\n",
 				memunitpool, m);
--- a/mafs.c
+++ b/mafs.c
@@ -98,7 +98,7 @@
 	formatinit();
 
 	initmemunitpool(nmemunits);
-	initextents(&frees);
+	initextents(&frees, "blocks");
 	iobufinit();
 
 	/*
--- a/reconcile.c
+++ b/reconcile.c
@@ -165,7 +165,7 @@
 	if(debug)
 		print("collect %s ", s->name);
 	s->es = emalloc(sizeof(Extents));
-	initextents(s->es);
+	initextents(s->es, s->name);
 	while((s->buf = Brdstr(&s->bp, '\n', 1)) != nil) {
 		p = s->buf;
 		start = strtoull(p, &ep, 10);
--- a/sub.c
+++ b/sub.c
@@ -78,20 +78,8 @@
 {
 	u64 blkno;
 	Iobuf *buf;
-	u8 repeat;
-	s8 st;
 
-	st = -1;
-	for(repeat = 0;
-		repeat < 10 && (st = balloc(&frees, len, &blkno)) < 0;
-		repeat++){
-		showextents(2, "out of free blocks: ", &frees);
-		if(sync()==0)
-			repeat = 9;
-	}
-	if(st < 0)
-		return nil;	/* the caller should trigger an Efull message */
-
+	blkno = balloc(&frees, len);
 	if(chatty9p > 1)
 		dprint("alloc %llud\n", blkno);
 
--- a/unused.c
+++ b/unused.c
@@ -97,7 +97,7 @@
 		show(&u);
 
 	/* identify unused blocks */
-	initextents(&unused);
+	initextents(&unused, "unused");
 	for(i = 0; i < nblocks; i++){
 		if(find(u.es, i) == 0){
 			add(&unused, i, 1);
@@ -136,7 +136,7 @@
 	if(debug)
 		print("collect %s ", s->name);
 	s->es = emalloc(sizeof(Extents));
-	initextents(s->es);
+	initextents(s->es, s->name);
 	while((s->buf = Brdstr(&s->bp, '\n', 1)) != nil) {
 		p = s->buf;
 		start = strtoull(p, &ep, 10);
--- a/used.c
+++ b/used.c
@@ -51,7 +51,7 @@
 	if(chatty9p)
 		print("%s %llud bytes %llud blocks\n", devfile, size, size/Blocksize);
 
-	initextents(&useds);
+	initextents(&useds, "useds");
 	checkdentry(Bdmagic, Tdentry, Qpmagic);
 	walkdirectory(Bdroot);
 	close(devfd);