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;
+}