ref: 21b2c1b13c06cb6c2cf7fc96d3ccf57433c948e9
parent: 095c8ea146b97d57c3a14e71f2b5d7e02595623f
author: 9ferno <[email protected]>
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