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);