ref: 2ae0be32e919e3981e3c5f1012cb9bf68b9d858a
parent: 99c900d718ea1343036656b7384af56bcad2f28f
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Dec 22 21:47:19 EST 2021
wip: start processing deadlists.
--- a/blk.c
+++ b/blk.c
@@ -169,7 +169,7 @@
}
Blk*
-logappend(Oplog *ol, Arena *a, vlong off, vlong len, int op)
+logappend(Oplog *ol, Arena *a, vlong off, vlong len, vlong val, int op)
{
Blk *pb, *lb;
vlong o;
@@ -220,7 +220,7 @@
PBIT64(p, off);
lb->logsz += 8;
if(op >= Log2wide){
- PBIT64(p+8, len);
+ PBIT64(p+8, val);
lb->logsz += 8;
}
/* this gets overwritten by the next append */
@@ -244,10 +244,10 @@
break;
}
}
- if((b = logappend(l, nil, bp.addr, Blksz, LogDead)) == nil)
+ if((b = logappend(l, nil, bp.addr, Blksz, bp.gen, LogDead)) == nil)
return -1;
- if(l->head == -1)
- l->head = b->bp.addr;
+ if(l->head.addr == -1)
+ l->head = b->bp;
if(l->tail != b)
l->tail = b;
return 0;
@@ -264,10 +264,10 @@
{
Blk *b;
- if((b = logappend(&a->log, a, off, Blksz, op)) == nil)
+ if((b = logappend(&a->log, a, off, Blksz, Blksz, op)) == nil)
return -1;
- if(a->log.head == -1)
- a->log.head = b->bp.addr;
+ if(a->log.head.addr == -1)
+ a->log.head = b->bp;
if(a->log.tail != b)
a->log.tail = b;
return 0;
@@ -274,21 +274,78 @@
}
int
+scandead(Bptr bp, int (*fn)(Bptr))
+{
+ vlong ent, off;
+ int op, i, n;
+ uvlong bh;
+ Bptr dead;
+ char *d;
+ Blk *b;
+
+Nextblk:
+ if((b = getblk(bp, GBnochk)) == nil)
+ return -1;
+ bh = GBIT64(b->data);
+ /* the hash covers the log and offset */
+ if(bh != siphash(b->data+8, Blkspc-8)){
+ werrstr("corrupt log");
+ return -1;
+ }
+ for(i = Loghdsz; i < Logspc; i += n){
+ d = b->data + i;
+ ent = GBIT64(d);
+ op = ent & 0xff;
+ off = ent & ~0xff;
+ n = (op >= Log2wide) ? 16 : 8;
+ switch(op){
+ case LogDead:
+ dead.addr = ent;
+ dead.hash = -1;
+ dead.gen = GBIT64(d+8);
+ fn(dead);
+ break;
+ case LogEnd:
+ dprint("log@%d: end\n", i);
+ /*
+ * since we want the next insertion to overwrite
+ * this, don't include the size in this entry.
+ */
+ b->logsz = i;
+ return 0;
+ case LogChain:
+ bp.addr = off & ~0xff;
+ bp.hash = -1;
+ bp.gen = -1;
+ dprint("log@%d: chain %B\n", i, bp);
+ b->logsz = i+n;
+ goto Nextblk;
+ break;
+ default:
+ n = 0;
+ dprint("log@%d: log op %d\n", i, op);
+ abort();
+ break;
+ }
+ }
+ return 0;
+}
+
+int
loadlog(Arena *a)
{
- vlong bp, ent, off, len;
+ vlong ent, off, len;
int op, i, n;
uvlong bh;
+ Bptr bp;
char *d;
Blk *b;
bp = a->log.head;
-
Nextblk:
- if((b = readblk(bp, 0)) == nil)
+ if((b = getblk(bp, GBnochk)) == nil)
return -1;
- cacheblk(b);
bh = GBIT64(b->data);
/* the hash covers the log and offset */
if(bh != siphash(b->data+8, Blkspc-8)){
@@ -311,8 +368,10 @@
b->logsz = i;
return 0;
case LogChain:
- bp = off & ~0xff;
- dprint("log@%d: chain %llx\n", i, bp);
+ bp.addr = off & ~0xff;
+ bp.hash = -1;
+ bp.gen = -1;
+ dprint("log@%d: chain %B\n", i, bp);
b->logsz = i+n;
goto Nextblk;
break;
@@ -424,12 +483,11 @@
return -1;
}
hd = b;
- ol.hash = -1;
- ol.head = b->bp.addr;
+ ol.head = b->bp;
ol.tail = b;
b->logsz = Loghdsz;
for(i = 0; i < n; i++)
- if((b = logappend(&ol, a, log[i].off, log[i].len, LogFree)) == nil)
+ if((b = logappend(&ol, a, log[i].off, log[i].len, log[i].len, LogFree)) == nil)
return -1;
p = b->data + b->logsz;
PBIT64(p, LogChain|graft);
@@ -438,12 +496,13 @@
if(syncblk(b) == -1)
return -1;
- oldhd = a->log.head;
- a->log.head = hd->bp.addr;
- a->log.hash = blkhash(hd);
+ oldhd = a->log.head.addr;
+ a->log.head.addr = hd->bp.addr;
+ a->log.head.hash = blkhash(hd);
+ a->log.head.gen = -1;
ab = a->b;
- PBIT64(ab->data + 0, a->log.head);
- PBIT64(ab->data + 8, a->log.hash);
+ PBIT64(ab->data + 0, a->log.head.addr);
+ PBIT64(ab->data + 8, a->log.head.hash);
finalize(ab);
if(syncblk(ab) == -1)
return -1;
@@ -684,6 +743,7 @@
getblk(Bptr bp, int flg)
{
Blk *b;
+ uvlong h;
if((b = lookupblk(bp.addr)) != nil)
return cacheblk(b);
@@ -698,13 +758,14 @@
qunlock(&blklock);
return nil;
}
- if(blkhash(b) != bp.hash){
+ h = blkhash(b);
+ if((flg&GBnochk) == 0 && h != bp.hash){
fprint(2, "corrupt block %B: %llx != %llx\n", bp, blkhash(b), bp.hash);
qunlock(&blklock);
abort();
return nil;
}
- b->bp.hash = bp.hash;
+ b->bp.hash = h;
b->bp.gen = bp.gen;
cacheblk(b);
qunlock(&blklock);
--- a/dat.h
+++ b/dat.h
@@ -245,7 +245,7 @@
enum {
GBraw = 1<<0,
GBwrite = 1<<1,
- GBunchk = 1<<2,
+ GBnochk = 1<<2,
};
enum {
@@ -289,9 +289,14 @@
LogDead , /* deadlist a block */
};
+struct Bptr {
+ vlong addr;
+ vlong hash;
+ vlong gen;
+};
+
struct Oplog {
- vlong head; /* log head */
- vlong hash; /* log head hash */
+ Bptr head;
Blk *tail; /* tail block open for writing */
};
@@ -312,12 +317,6 @@
QLock *wrlk; /* write lock on fd */
int sz; /* the size of the message buf */
uchar buf[];
-};
-
-struct Bptr {
- vlong addr;
- vlong hash;
- vlong gen;
};
struct Tree {
--- a/dump.c
+++ b/dump.c
@@ -339,8 +339,7 @@
for(i = 0; i < Ndead; i++){
fprint(fd, "\tdeadlist %d\n", i);
fprint(fd, "\t\tprev:\t%llx\n", t.prev[i]);
- fprint(fd, "\t\tfheadp:\t%llx\n", t.dead[i].head);
- fprint(fd, "\t\tfheadh:\t%llx\n", t.dead[i].hash);
+ fprint(fd, "\t\tfhead:\t%B\n", t.dead[i].head);
if(t.dead[i].tail != nil){
fprint(fd, "\t\tftailp:%llx\n", t.dead[i].tail->bp.addr);
fprint(fd, "\t\tftailh:%llx\n", t.dead[i].tail->bp.hash);
--- a/fns.h
+++ b/fns.h
@@ -42,6 +42,7 @@
void loadfs(char*);
int sync(void);
int loadlog(Arena*);
+int scandead(Bptr, int (*)(Bptr));
int endfs(void);
int compresslog(Arena*);
void setval(Blk*, int, Kvp*);
--- a/load.c
+++ b/load.c
@@ -22,8 +22,9 @@
if((b = readblk(o, 0)) == nil)
return -1;
a->b = b;
- a->log.head = GBIT64(b->data+0);
- a->log.hash = GBIT64(b->data+8);
+ a->log.head.addr = GBIT64(b->data+0);
+ a->log.head.hash = GBIT64(b->data+8);
+ a->log.head.gen = -1;
if(loadlog(a) == -1)
return -1;
if(compresslog(a) == -1)
--- a/mkfile
+++ b/mkfile
@@ -13,7 +13,7 @@
main.$O\
pack.$O\
ream.$O\
- sync.$O\
+ snap.$O\
tree.$O\
HFILES=\
--- a/pack.c
+++ b/pack.c
@@ -308,7 +308,7 @@
unpacktree(Tree *t, char *p, int sz)
{
int i, j;
- Bptr bp;
+ Bptr bp, head;
Blk *b;
assert(sz >= Treesz);
@@ -319,11 +319,12 @@
t->bp.hash = GBIT64(p); p += 8;
t->bp.gen = GBIT64(p); p += 8;
for(i = 0; i < Ndead; i++){
- t->prev[i] = GBIT64(p); p += 8;
- t->dead[i].head = GBIT64(p); p += 8;
- t->dead[i].hash = GBIT64(p); p += 8;
- bp.addr = GBIT64(p); p += 8;
- bp.hash = GBIT64(p); p += 8;
+ t->prev[i] = GBIT64(p); p += 8;
+ head.addr = GBIT64(p); p += 8;
+ head.hash = GBIT64(p); p += 8;
+ head.gen = -1;
+ bp.addr = GBIT64(p); p += 8;
+ bp.hash = GBIT64(p); p += 8;
bp.gen = -1;
if(bp.addr == -1)
continue;
@@ -332,6 +333,7 @@
putblk(t->dead[j].tail);
return nil;
}
+ t->dead[i].head = head;
t->dead[i].tail = b;
cacheblk(b);
}
@@ -342,6 +344,7 @@
packtree(char *p, int sz, Tree *t)
{
vlong tladdr, tlhash;
+ Bptr head;
Blk *tl;
int i;
@@ -362,11 +365,12 @@
tladdr = tl->bp.addr;
tlhash = tl->bp.hash;
}
- PBIT64(p, t->prev[i]); p += 8;
- PBIT64(p, t->dead[i].head); p += 8;
- PBIT64(p, t->dead[i].hash); p += 8;
- PBIT64(p, tladdr); p += 8;
- PBIT64(p, tlhash); p += 8;
+ head = t->dead[i].head;
+ PBIT64(p, t->prev[i]); p += 8;
+ PBIT64(p, head.addr); p += 8;
+ PBIT64(p, head.hash); p += 8;
+ PBIT64(p, tladdr); p += 8;
+ PBIT64(p, tlhash); p += 8;
}
return p;
}
--- a/ream.c
+++ b/ream.c
@@ -68,8 +68,9 @@
t.bp = r->bp;
for(i = 0; i < Ndead; i++){
t.prev[i] = -1;
- t.dead[i].head = -1;
- t.dead[i].hash = -1;
+ t.dead[i].head.addr = -1;
+ t.dead[i].head.hash = -1;
+ t.dead[i].head.gen = -1;
t.dead[i].tail = nil;
}
p = packtree(vbuf, sizeof(vbuf), &t);
@@ -90,7 +91,10 @@
sysfatal("ream: %r");
addr += Blksz; /* arena header */
- a->log.head = -1;
+ a->log.head.addr = -1;
+ a->log.head.hash = -1;
+ a->log.head.gen = -1;
+
memset(b, 0, sizeof(Blk));
b->type = Tlog;
b->bp.addr = addr;
--- a/snap.c
+++ b/snap.c
@@ -104,7 +104,36 @@
return nil;
}
+int
+snapfreebp(Bptr)
+{
+ return 0;
+}
+
+int
+movedead(Bptr)
+{
+ return 0;
+}
+
char*
+deletesnap(Tree *s)
+{
+ Tree p;
+ char *e;
+ int i;
+
+ scandead(s->dead[0].head, snapfreebp);
+// for(i = 1; i < Ndead-1; i++){
+// if((e = opensnap(&p, s->prev[i])) != nil)
+// return e;
+// graftdead(s, s->prev[i], &s->dead[i]);
+// }
+ scandead(s->dead[Ndead-1].head, movedead);
+ return nil;
+}
+
+char*
labelsnap(vlong gen, char *name)
{
return modifysnap(gen, name, 0);
@@ -165,88 +194,12 @@
putblk(t->dead[Ndead-1].tail);
for(i = Ndead-1; i >= 0; i--){
t->prev[i] = i == 0 ? gen : t->prev[i-1];
- t->dead[i].head = -1;
- t->dead[i].hash = -1;
+ t->dead[i].head.addr = -1;
+ t->dead[i].head.hash = -1;
+ t->dead[i].head.gen = -1;
t->dead[i].tail = nil;
}
*genp = gen;
*oldp = t->prev[0];
return nil;
-}
-
-int
-sync(void)
-{
- int i, r;
- Blk *b, *s;
- Arena *a;
-
- qlock(&fs->snaplk);
- r = 0;
- s = fs->super;
- fillsuper(s);
- enqueue(s);
-
- for(i = 0; i < fs->narena; i++){
- a = &fs->arenas[i];
- finalize(a->log.tail);
- if(syncblk(a->log.tail) == -1)
- r = -1;
- }
- for(b = fs->chead; b != nil; b = b->cnext){
- if(!(b->flag & Bdirty))
- continue;
- if(syncblk(b) == -1)
- r = -1;
- }
- if(r != -1)
- r = syncblk(s);
-
- qunlock(&fs->snaplk);
- return r;
-}
-
-void
-quiesce(int tid)
-{
- int i, allquiesced;
- Bfree *p, *n;
-
- lock(&fs->activelk);
- allquiesced = 1;
- fs->active[tid]++;
- for(i = 0; i < fs->nproc; i++){
- /*
- * Odd parity on quiescence implies
- * that we're between the exit from
- * and waiting for the next message
- * that enters us into the critical
- * section.
- */
- if((fs->active[i] & 1) == 0)
- continue;
- if(fs->active[i] == fs->lastactive[i])
- allquiesced = 0;
- }
- if(allquiesced)
- for(i = 0; i < fs->nproc; i++)
- fs->lastactive[i] = fs->active[i];
- unlock(&fs->activelk);
- if(!allquiesced)
- return;
-
- lock(&fs->freelk);
- p = nil;
- if(fs->freep != nil){
- p = fs->freep->next;
- fs->freep->next = nil;
- }
- unlock(&fs->freelk);
-
- while(p != nil){
- n = p->next;
- reclaimblk(p->bp);
- p = n;
- }
- fs->freep = fs->freehd;
}