ref: 0c6f17f8c8e759c15cf94de01d2e754978334b96
parent: 55b15443d3f318a3c488d760763cb3e232cacdd9
author: glenda <[email protected]>
date: Wed Dec 15 18:46:57 EST 2021
blk: refactor allocation log to list This prepares for appending to deadlists.
--- a/blk.c
+++ b/blk.c
@@ -13,6 +13,7 @@
};
static vlong blkalloc_lk(Arena*);
+static vlong blkalloc(void);
static int blkdealloc_lk(vlong);
static void cachedel(vlong);
@@ -75,17 +76,11 @@
}
static Arena*
-pickarena(vlong hint)
+pickarena(void)
{
long n;
- n = -1; /* shut up, ken */
- if(hint > 0 || hint < fs->narena)
- n = hint / fs->arenasz;
- else if(hint == -1)
- n = ainc(&fs->nextarena) % fs->narena;
- else
- abort();
+ n = (ainc(&fs->roundrobin)/1024) % fs->narena;
return &fs->arenas[n];
}
@@ -174,17 +169,22 @@
}
Blk*
-logappend(Arena *a, Blk *lb, vlong off, vlong len, int op)
+logappend(Oplog *ol, Arena *a, vlong off, vlong len, int op)
{
- Blk *pb;
+ Blk *pb, *lb;
vlong o;
char *p;
assert(off % Blksz == 0);
assert(op == LogAlloc || op == LogFree);
+ lb = ol->tail;
if(lb == nil || lb->logsz > Logspc - 8){
pb = lb;
- if((o = blkalloc_lk(a)) == -1)
+ if(a == nil)
+ o = blkalloc();
+ else
+ o = blkalloc_lk(a);
+ if(o == -1)
return nil;
if((lb = mallocz(sizeof(Blk), 1)) == nil)
return nil;
@@ -201,7 +201,7 @@
return nil;
}
- a->logtl = lb;
+ ol->tail = lb;
if(pb != nil){
p = pb->data + pb->logsz;
PBIT64(p + 0, lb->bp.addr|LogChain);
@@ -239,12 +239,12 @@
{
Blk *b;
- if((b = logappend(a, a->logtl, off, Blksz, op)) == nil)
+ if((b = logappend(&a->log, a, off, Blksz, op)) == nil)
return -1;
- if(a->log == -1)
- a->log = b->bp.addr;
- if(b != a->logtl)
- a->logtl = b;
+ if(a->log.head == -1)
+ a->log.head = b->bp.addr;
+ if(b != a->log.tail)
+ a->log.tail = b;
return 0;
}
@@ -258,7 +258,7 @@
int op, i, n;
- bp = a->log;
+ bp = a->log.head;
Nextblk:
if((b = readblk(bp, 0)) == nil)
@@ -329,6 +329,7 @@
vlong v, bp, nb, graft, oldhd;
int i, n, sz;
Blk *hd, *ab, *b;
+ Oplog ol;
char *p;
/*
@@ -362,14 +363,14 @@
}
graft = b->bp.addr;
- if(a->logtl != nil){
- finalize(a->logtl);
- if(syncblk(a->logtl) == -1){
+ if(a->log.tail != nil){
+ finalize(a->log.tail);
+ if(syncblk(a->log.tail) == -1){
free(b);
return -1;
}
}
- a->logtl = b;
+ a->log.tail = b;
/*
* Prepare what we're writing back.
@@ -399,9 +400,12 @@
return -1;
}
hd = b;
+ ol.hash = -1;
+ ol.head = b->bp.addr;
+ ol.tail = b;
b->logsz = Loghdsz;
for(i = 0; i < n; i++)
- if((b = logappend(a, b, log[i].off, log[i].len, LogFree)) == nil)
+ if((b = logappend(&ol, a, log[i].off, log[i].len, LogFree)) == nil)
return -1;
p = b->data + b->logsz;
PBIT64(p, LogChain|graft);
@@ -410,12 +414,12 @@
if(syncblk(b) == -1)
return -1;
- oldhd = a->log;
- a->log = hd->bp.addr;
- a->logh = blkhash(hd);
+ oldhd = a->log.head;
+ a->log.head = hd->bp.addr;
+ a->log.hash = blkhash(hd);
ab = a->b;
- PBIT64(ab->data + 0, a->log);
- PBIT64(ab->data + 8, a->logh);
+ PBIT64(ab->data + 0, a->log.head);
+ PBIT64(ab->data + 8, a->log.hash);
finalize(ab);
if(syncblk(ab) == -1)
return -1;
@@ -444,8 +448,8 @@
unlock(a);
}
}
- finalize(a->logtl);
- if(syncblk(a->logtl) == -1)
+ finalize(a->log.tail);
+ if(syncblk(a->log.tail) == -1)
return -1;
return 0;
}
@@ -502,8 +506,8 @@
return r;
}
-vlong
-blkalloc(vlong hint)
+static vlong
+blkalloc(void)
{
Arena *a;
vlong b;
@@ -511,12 +515,11 @@
tries = 0;
Again:
- a = pickarena(hint);
+ a = pickarena();
if(a == nil || tries == fs->narena){
werrstr("no empty arenas");
return -1;
}
- lock(a);
/*
* TODO: there's an extreme edge case
* here.
@@ -530,6 +533,7 @@
* correctly.
*/
tries++;
+ lock(a);
if((b = blkalloc_lk(a)) == -1){
unlock(a);
goto Again;
@@ -548,7 +552,7 @@
Blk *b;
vlong bp;
- if((bp = blkalloc(-1)) == -1)
+ if((bp = blkalloc()) == -1)
return nil;
if((b = lookupblk(bp)) == nil){
if((b = mallocz(sizeof(Blk), 1)) == nil)
--- a/dat.h
+++ b/dat.h
@@ -18,6 +18,7 @@
typedef struct Bucket Bucket;
typedef struct Chan Chan;
typedef struct Tree Tree;
+typedef struct Oplog Oplog;
typedef struct Mount Mount;
enum {
@@ -347,7 +348,7 @@
Arena *arenas;
int narena;
- long nextarena;
+ long roundrobin;
vlong arenasz;
Lock fidtablk;
@@ -364,18 +365,20 @@
int cmax;
};
+struct Oplog {
+ vlong head; /* log head */
+ vlong hash; /* log head hash */
+ Blk *tail; /* tail block open for writing */
+};
+
struct Arena {
Lock;
Avltree *free;
Avltree *partial;
-
- vlong log; /* log head */
- vlong logh; /* log head hash */
- Blk *logtl; /* tail block open for writing */
Blk *b; /* arena block */
-
Blk **q; /* write queue */
vlong nq;
+ Oplog log;
};
struct Key{
--- a/load.c
+++ b/load.c
@@ -22,8 +22,8 @@
if((b = readblk(o, 0)) == nil)
return -1;
a->b = b;
- a->log = GBIT64(b->data+0);
- a->logh = GBIT64(b->data+8);
+ a->log.head = GBIT64(b->data+0);
+ a->log.hash = GBIT64(b->data+8);
if(loadlog(a) == -1)
return -1;
if(compresslog(a) == -1)
--- a/ream.c
+++ b/ream.c
@@ -83,7 +83,7 @@
sysfatal("ream: %r");
addr += Blksz; /* arena header */
- a->log = -1;
+ a->log.head = -1;
memset(b, 0, sizeof(Blk));
b->type = Tlog;
b->bp.addr = addr;
--- a/sync.c
+++ b/sync.c
@@ -136,8 +136,8 @@
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
- finalize(a->logtl);
- if(syncblk(a->logtl) == -1)
+ finalize(a->log.tail);
+ if(syncblk(a->log.tail) == -1)
r = -1;
}
for(b = fs->chead; b != nil; b = b->cnext){