code: mafs

Download patch

ref: ec41f2072998cb42f5ce26d8f462fb21707ef4c1
parent: 21b2c1b13c06cb6c2cf7fc96d3ccf57433c948e9
author: 9ferno <gophone2015@gmail.com>
date: Thu Oct 20 00:01:44 EDT 2022

tied the Wbuf to the Iobuf to ensure that we do not free dirty Iobufs

--- a/9p.c
+++ b/9p.c
@@ -889,6 +889,7 @@
 shutdown(void)
 {
 	int i, a;
+	u64 n;
 /*	User *u, *v; */
 	char srvfilename[Namelen];
 
@@ -898,6 +899,11 @@
 	fsok(1);
 //	showextents(&frees);
 	shuttingdown = 1;
+	while((n=pendingwrites())>0){
+		if(chatty9p > 1)
+		dprint("shutdown: pendingwrites %llud of write queue\n", n);
+		sleep(1000);
+	}
 	savefrees(Bdfrees);
 //	dprint("&buf.isempty %#p\n", &buf.isempty);
 //	rwakeupall(&buf.isempty);
@@ -904,6 +910,11 @@
 	for(i = 0; i< 10; i++){
 		a = stopworkers();
 		sleep(a*1000);
+	}
+	while((n=pendingwrites())>0){
+		if(chatty9p > 1)
+		dprint("shutdown: pendingwrites %llud of frees\n", n);
+		sleep(1000);
 	}
 	stopwriter();
 	if(a > 1){ /* 1 for this running process */
--- a/all.h
+++ b/all.h
@@ -62,6 +62,8 @@
 		u8	*xiobuf;	/* "real" buffer pointer */
 		Content *io;	/* cast'able to contents */
 	};
+	u32	dirties;
+	u8 tofree;
 };
 
 extern	u32	nbuckets;		/* n hash buckets for i/o */
@@ -83,6 +85,7 @@
 void	initwriter(void);
 void	putwrite(Iobuf *b);
 void	stopwriter(void);
+u64		pendingwrites(void);
 
 /* routines to manipulate the contents */
 Iobuf*	allocblocks(u16 len, int tag, u64 qpath);
--- a/sub.c
+++ b/sub.c
@@ -121,10 +121,14 @@
 	if(buf->readers)
 		panic("freeblockbuf without Bwritable");
 
-	/* clear the buf to avoid leaks on reuse */
-	memset(buf->io, 0, buf->len*Rawblocksize);
-	bfree(&frees, buf->blkno, buf->len);
-	putbuffree(buf);
+	if(buf->dirties)
+		buf->tofree = 1;
+	else{
+		/* clear the buf to avoid leaks on reuse */
+		memset(buf->io, 0, buf->len*Rawblocksize);
+		bfree(&frees, buf->blkno, buf->len);
+		putbuffree(buf);
+	}
 }
 
 /* add the block to the extents used to manage free blocks */
--- a/writer.c
+++ b/writer.c
@@ -28,6 +28,7 @@
 	u64	blkno;		/* block number on the disk, primary key */
 	u16 len;		/* number of blocks of data xiobuf points to */
 	Wbuf *prev, *next;
+	Iobuf *iobuf;
 	union{
 		u8	payload;	/* "real" contents */
 		Content io;	/* cast'able to contents */
@@ -136,6 +137,8 @@
 	drts.n++;
 	if(drts.n == 1)
 		rwakeup(&drts.isempty);
+	b->dirties++;
+	w->iobuf = b;
 	if(chkwunlock(b) == 0){
 		showbuf(b);
 		panic("putwrite chkwunlock(p) == 0 called by %#p\n", getcallerpc(&b));
@@ -169,6 +172,12 @@
 	n = p->blkno;
 	if(chatty9p > 4)
 	dprint("dowrite %llud wunlock()'ed\n", n);
+	wlock(p->iobuf);
+	p->iobuf->dirties--;
+	if(p->iobuf->tofree && p->iobuf->dirties == 0)
+		freeblockbuf(p->iobuf);
+	else
+		wunlock(p->iobuf);
 	free(p);
 }
 
@@ -234,3 +243,13 @@
 			drts.tail == nil ? 0 : drts.tail->blkno);
 }
 
+u64
+pendingwrites(void)
+{
+	u64 n;
+
+	qlock(&drts.lck);
+	n = drts.n;
+	qunlock(&drts.lck);
+	return n;
+}