code: mafs

Download patch

ref: 21b2c1b13c06cb6c2cf7fc96d3ccf57433c948e9
parent: 095c8ea146b97d57c3a14e71f2b5d7e02595623f
author: 9ferno <gophone2015@gmail.com>
date: Wed Oct 19 15:40:13 EDT 2022

have a separate writer queue

--- a/all.h
+++ b/all.h
@@ -62,9 +62,6 @@
 		u8	*xiobuf;	/* "real" buffer pointer */
 		Content *io;	/* cast'able to contents */
 	};
-
-	u8 dirty;		/* to identify buffers which are yet to be written */
-	Iobuf *prevdirty, *nextdirty;
 };
 
 extern	u32	nbuckets;		/* n hash buckets for i/o */
@@ -85,7 +82,6 @@
 /* writer functions */
 void	initwriter(void);
 void	putwrite(Iobuf *b);
-Iobuf *rmwrite(Iobuf *b);
 void	stopwriter(void);
 
 /* routines to manipulate the contents */
--- a/dentry.c
+++ b/dentry.c
@@ -101,7 +101,7 @@
 		n = nperindunit(tag);
 		if(reli/n >= Nindperblock){
 			panic("updateindblock invalid reli: indblkno %llud reli %llud tag %s"
-					" directblkno %llud len %llud reli/n %llud nperindunit(tag) %llud\n",
+					" directblkno %llud len %ud reli/n %llud nperindunit(tag) %d\n",
 					indblkno, reli, tagnames[tag], blkno, len, reli/n, Nindperblock);
 			dprint("%s",errstring[Ephase]);
 			return 0;
@@ -113,7 +113,7 @@
 	}else{
 		if(reli >= Nspanidperblock){
 			panic("updateindblock invalid reli: indblkno %llud reli %llud tag %s"
-					" directblkno %llud len %llud Nspanidperblock %llud\n",
+					" directblkno %llud len %ud Nspanidperblock %d\n",
 					indblkno, reli, tagnames[tag], blkno, len, Nspanidperblock);
 			dprint("%s",errstring[Ephase]);
 			return 0;
--- a/iobuf.c
+++ b/iobuf.c
@@ -105,8 +105,6 @@
 				wlock(p);
 				if(chatty9p > 4)
 					dprint("	after wlock() blkno %llud\n", blkno);
-				if(p->dirty)
-					panic("p->dirty with p->len != len\n");
 				free(p->xiobuf);
 				p->xiobuf = emalloc9p(len*Rawblocksize);
 				p->len = len;
@@ -128,13 +126,6 @@
 				wlock(p);
 				if(chatty9p > 4)
 					dprint("	after wlock() blkno %llud\n", blkno);
-				/* as we lock from top down, this should ensure that the
-					lower blocks in the hierarchy are removed from the write
-					queue only after the top blocks have been removed or erased.
-				 */
-				if(p->dirty)
-					rmwrite(p); /* remove the pending write as it will be
-									written by putbuf() anyway */
 			}
 			decref(p);
 			return p;
@@ -149,14 +140,9 @@
 		Ncollisions is a soft limit.
 	 */
 	if(ncollisions >= Ncollisions){
-Another:
 		do{
 			p = s->back;
-			if(p->ref == 0 && p->dirty == 0 && canwlock(p)){
-				if(p->dirty){
-					wunlock(p);
-					goto Another;
-				}
+			if(p->ref == 0 && canwlock(p)){
 				if(p->len != len){
 					free(p->xiobuf);
 					p->xiobuf = emalloc9p(len*Rawblocksize);
@@ -355,7 +341,6 @@
 		if(canwlock(p)){
 			panic("putbuffree: buffer not locked %llud\n", p->blkno);
 		}
-		p->dirty = 0;
 		if(chkwunlock(p) == 0){
 			showbuf(p);
 			panic("putbuffree chkwunlock(p) == 0 called by %#p\n", getcallerpc(&p));
--- a/writer.c
+++ b/writer.c
@@ -13,44 +13,56 @@
 
 /* below is from nemo's Pg 252 */
 typedef	struct	Dirties	Dirties;
+typedef	struct	Wbuf	Wbuf;
 
 struct Dirties
 {
 	QLock lck;
-	Iobuf *head, *tail;
+	Wbuf *head, *tail;
 	s32 n;
 	Rendez isempty;
 } drts = {0};
 
+struct Wbuf
+{
+	u64	blkno;		/* block number on the disk, primary key */
+	u16 len;		/* number of blocks of data xiobuf points to */
+	Wbuf *prev, *next;
+	union{
+		u8	payload;	/* "real" contents */
+		Content io;	/* cast'able to contents */
+	};
+};
+
 u8 stopwrites = 0;
 static void stats(void);
 
-static Iobuf *
-pluck(Iobuf *b)
+static Wbuf *
+pluck(Wbuf *b)
 {
 	if(b == nil)
 		return nil;
-	else if(b->prevdirty == nil && b->nextdirty == nil){
+	else if(b->prev == nil && b->next == nil){
 		/* only one */
 		drts.head = drts.tail = nil;
 		goto Done;
-	}else if(b->prevdirty == nil){
+	}else if(b->prev == nil){
 		/* first in the linked list */
-		drts.head = b->nextdirty;
-		b->nextdirty = nil;
-		drts.head->prevdirty = nil;
+		drts.head = b->next;
+		b->next = nil;
+		drts.head->prev = nil;
 		goto Done;
-	}else if(b->prevdirty != nil && b->nextdirty != nil){
+	}else if(b->prev != nil && b->next != nil){
 		/* somewhere in the middle */
-		b->nextdirty->prevdirty = b->prevdirty;
-		b->prevdirty->nextdirty = b->nextdirty;
-		b->prevdirty = b->nextdirty = nil;
+		b->next->prev = b->prev;
+		b->prev->next = b->next;
+		b->prev = b->next = nil;
 		goto Done;
-	}else if(b->nextdirty == nil){
+	}else if(b->next == nil){
 		/* last in the linked list */
-		drts.tail = b->prevdirty;
-		b->prevdirty->nextdirty = nil;
-		b->prevdirty = nil;
+		drts.tail = b->prev;
+		b->prev->next = nil;
+		b->prev = nil;
 		goto Done;
 	}
 	panic("pluck should not be here\n");
@@ -62,30 +74,10 @@
 	return b;
 }
 
-/* the Iobuf should be wlock()'ed at entry */
-Iobuf *
-rmwrite(Iobuf *b)
-{
-	Iobuf *p;
-
-	qlock(&drts.lck);
-	if(chatty9p > 4){
-		dprint("rmwrite start b->blkno %llud\n", b->blkno);
-		stats();
-	}
-	p = pluck(b);
-	if(chatty9p > 4 && p!=nil){
-		dprint("rmwrite removed p->blkno %llud\n", p->blkno);
-		stats();
-	}
-	qunlock(&drts.lck);
-	return p;
-}
-
-Iobuf *
+Wbuf *
 getwrite(void)
 {
-	Iobuf *b;
+	Wbuf *b;
 
 	qlock(&drts.lck);
 	if(drts.n == 0){
@@ -101,7 +93,7 @@
 	}
 	/* using canwlock() here as getbuf() could
 		have wlock()'ed the Iobuf too */
-	if(drts.head != nil && canwlock(drts.head))
+	if(drts.head != nil)
 		b = pluck(drts.head);
 	else
 		b = nil;
@@ -117,6 +109,8 @@
 void
 putwrite(Iobuf *b)
 {
+	Wbuf *w;
+
 	qlock(&drts.lck);
 	if(chatty9p > 4){
 		dprint("putwrite start p->blkno %llud\n", b->blkno);
@@ -128,13 +122,16 @@
 		if(chatty9p > 4)
 			stats();
 	}
-	b->dirty = 1;
+	w = emalloc9p(sizeof(Wbuf)+(b->len*Rawblocksize));
+	w->blkno = b->blkno;
+	w->len = b->len;
+	memcpy(&w->io, b->io, b->len*Rawblocksize);
 	if(drts.head == nil){
-		drts.head = drts.tail = b;
+		drts.head = drts.tail = w;
 	}else{
-		drts.tail->nextdirty = b;
-		b->prevdirty = drts.tail;
-		drts.tail = b;
+		drts.tail->next = w;
+		w->prev = drts.tail;
+		drts.tail = w;
 	}
 	drts.n++;
 	if(drts.n == 1)
@@ -151,7 +148,7 @@
 }
 
 void
-dowrite(Iobuf *p)
+dowrite(Wbuf *p)
 {
 	u64 n;
 
@@ -161,28 +158,24 @@
 	}
 	if(chatty9p > 4)
 		dprint("dowrite p->blkno %llud locked\n", p->blkno);
-	p->io->dirty = 1;
-	if((n = devwrite(p->blkno, p->io, p->len)) != p->len*Rawblocksize){
+	p->io.dirty = 1;
+	if((n = devwrite(p->blkno, &p->payload, p->len)) != p->len*Rawblocksize){
 		dprint("%s\n", errstring[Esystem]);
 		panic("error writing block %llud: %llud bytes: %r\n",
 				p->blkno, n);
 	}
-	p->io->dirty = 0;
+	p->io.dirty = 0;
 	devwritedirtyclear(p->blkno);
-	p->dirty = 0;
 	n = p->blkno;
-	if(chkwunlock(p) == 0){
-		showbuf(p);
-		panic("dowrite chkwunlock(p) == 0 called by %#p\n", getcallerpc(&p));
-	}
 	if(chatty9p > 4)
 	dprint("dowrite %llud wunlock()'ed\n", n);
+	free(p);
 }
 
 void
 initwriter(void)
 {
-	Iobuf *b;
+	Wbuf *b;
 	char name[Namelen];
 
 	// set the locks used by the Rendezes