ref: 34be16ef74b0c991850ee82931e9bd21f01a0a4f
parent: c25ea72c90893cf97d313178f5e2a38077cd9cd4
author: Ori Bernstein <[email protected]>
date: Sun Dec 12 22:01:42 EST 2021
sync: separate snapshots from dataset names
--- a/blk.c
+++ b/blk.c
@@ -728,7 +728,10 @@
b->freed = getcallerpc(&b);
unlock(b);
dprint("freeing block %B @ %ld, from 0x%p\n", b->bp, b->ref, getcallerpc(&b));
- freebp(b->bp);
+ if(b->bp.gen == fs->nextgen)
+ freebp(b->bp);
+// else
+// deadlist(b->bp);
}
void
--- a/check.c
+++ b/check.c
@@ -260,29 +260,16 @@
void
showfs(int fd, char **ap, int na)
{
- char *p, *e, *name, kbuf[Kvmax], kvbuf[Kvmax];;
+ char *e, *name;
Tree t;
- Key k;
- Kvp kv;
- name = (na == 0) ? "main" : ap[0];
- k.k = kbuf;
- k.k[0] = Ksnap;
- k.nk = 1+snprint(k.k+1, sizeof(kbuf)-1, "%s", name);
- if((e = btlookup(&fs->snap, &k, &kv, kvbuf, sizeof(kvbuf))) != nil){
- fprint(fd, "lookup %K: %s\n", &k, e);
+ name = "main";
+ if(na == 1)
+ name = ap[0];
+ if((e = opensnap(&t, name)) != nil){
+ fprint(fd, "open %s: %s\n", name, e);
return;
}
- if(kv.nv != Rootsz+Ptrsz){
- fprint(fd, "bad snap %P\n", &kv);
- return;
- }
-
- p = kv.v;
- t.ht = GBIT32(p); p += 4;
- t.bp.addr = GBIT64(p); p += 8;
- t.bp.hash = GBIT64(p); p += 8;
- t.bp.gen = GBIT64(p);
showtree(fd, &t, name);
}
--- a/dat.h
+++ b/dat.h
@@ -48,6 +48,8 @@
Ptrsz = 24, /* off, hash, gen */
Fillsz = 2, /* block fill count */
Offksz = 17, /* type, qid, off */
+ Snapsz = 9, /* tag, snapid */
+ Treesz = 4+Ptrsz+Ptrsz, /* height, root, deadlist */
Kvmax = Keymax + Inlmax, /* Key and value */
Kpmax = Keymax + Ptrsz, /* Key and pointer */
@@ -70,8 +72,8 @@
*/
Kdat, /* qid[8] off[8] => ptr[16]: pointer to data page */
Kent, /* pqid[8] name[n] => dir[n]: serialized Dir */
- Ksnap, /* sid[8] => ref[8], tree[24]: snapshot root */
Kdset, /* name[] => snapid[]: dataset (snapshot ref) */
+ Ksnap, /* sid[8] => ref[8], tree[52]: snapshot root */
Ksuper, /* qid[8] => pqid[8]: parent dir */
};
@@ -252,6 +254,7 @@
struct Tree {
Lock lk;
Bptr bp;
+ Bptr dp;
int ht;
};
@@ -290,8 +293,8 @@
Tree snap;
Lock qidlk;
- vlong nextqid;
- vlong nextgen; /* unlocked: only touched by mutator thread */
+ uvlong nextqid;
+ uvlong nextgen; /* unlocked: only touched by mutator thread */
Arena *arenas;
int narena;
@@ -371,11 +374,8 @@
struct Mount {
long ref;
- Msg m;
- char kbuf[Keymax];
- char vbuf[Rootsz+Ptrsz];
+ char *name;
Tree root;
- Bptr dead;
};
struct Fid {
--- a/dump.c
+++ b/dump.c
@@ -25,8 +25,11 @@
case Kent: /* pqid[8] name[n] => dir[n]: serialized Dir */
n = fmtprint(fmt, "ent dir:%llx, name:\"%.*s\")", GBIT64(k->k+1), k->nk-11, k->k+11);
break;
+ case Kdset: /* name[n] => tree[24]: snapshot ref */
+ n = fmtprint(fmt, "dset name:\"%.*s\"", k->nk-1, k->k+1);
+ break;
case Ksnap: /* name[n] => tree[24]: snapshot root */
- n = fmtprint(fmt, "snap name:\"%.*s\"", k->nk-1, k->k+1);
+ n = fmtprint(fmt, "snap id:\"%llx\"", GBIT64(k->k+1));
break;
case Ksuper: /* qid[8] => pqid[8]: parent dir */
n = fmtprint(fmt, "up parent:%llx ptr:%llx", GBIT64(k->k+1), GBIT64(k->k+9));
@@ -101,6 +104,9 @@
bp.hash = GBIT64(v->v+12);
bp.gen = GBIT64(v->v+20);
n = fmtprint(fmt, "ht:%d, ptr:%B", ht, bp);
+ break;
+ case Kdset:
+ n = fmtprint(fmt, "snap id:\"%llx\"", GBIT64(v->v+1));
break;
case Ksuper: /* qid[8] => pqid[8]: parent dir */
n = fmtprint(fmt, "parent: %llx", GBIT64(v->v));
--- a/fns.h
+++ b/fns.h
@@ -30,8 +30,8 @@
u32int ihash(vlong);
void finalize(Blk*);
char* fillsuper(Blk*);
-char* snapshot(Mount*);
-char* loadsnap(Tree*, char*);
+char* snapshot(Tree*, char*, int);
+char* opensnap(Tree*, char*);
uvlong siphash(void*, usize);
void reamfs(char*);
int loadarena(Arena*, vlong);
@@ -119,4 +119,5 @@
void runcons(int, void*);
/* it's in libc... */
-extern int cas(long *, long, long);
+extern int cas(long*, long, long);
+extern int cas64(u64int*, u64int, u64int);
\ No newline at end of file
--- a/fs.c
+++ b/fs.c
@@ -483,10 +483,10 @@
static void
fsattach(Fmsg *m, int iounit)
{
- char *p, *ep, dbuf[Kvmax], kvbuf[Kvmax];
+ char *e, *p, *ep, dbuf[Kvmax], kvbuf[Kvmax];
int err;
Mount *mnt;
- Dent *e;
+ Dent *de;
Fcall r;
Kvp kv;
Key dk;
@@ -498,34 +498,14 @@
return;
}
- if(1+strlen(m->aname) >= sizeof(mnt->kbuf)){
- rerror(m, Ename);
- return;
- }
print("attach %s\n", m->aname);
- mnt->m.k = mnt->kbuf;
- mnt->m.k[0] = Ksnap;
- mnt->m.nk = 1+snprint(mnt->m.k+1, sizeof(mnt->kbuf)-1, "%s", m->aname);
- mnt->m.v = mnt->vbuf;
- mnt->m.nv = sizeof(mnt->vbuf);
- if(btlookup(&fs->snap, &mnt->m, &kv, kvbuf, sizeof(kvbuf)) != nil){
- rerror(m, Enosnap);
+ mnt->name = strdup(m->aname);
+ if((e = opensnap(&mnt->root, m->aname)) != nil){
+ rerror(m, e);
return;
}
+print("got root %B\n", mnt->root.bp);
- if(kv.nv != Rootsz+Ptrsz){
- rerror(m, Efs);
- return;
- }
- p = kv.v;
- mnt->root.ht = GBIT32(p); p += 4;
- mnt->root.bp.addr = GBIT64(p); p += 8;
- mnt->root.bp.hash = GBIT64(p); p += 8;
- mnt->root.bp.gen = GBIT64(p); p += 8;
- mnt->dead.addr = GBIT64(p); p += 8;
- mnt->dead.hash = GBIT64(p); p += 8;
- mnt->dead.gen = GBIT64(p);
-
err = 0;
p = dbuf;
ep = dbuf + sizeof(dbuf);
@@ -544,7 +524,7 @@
rerror(m, Efs);
return;
}
- if((e = getdent(-1, &d)) == nil){
+ if((de = getdent(-1, &d)) == nil){
rerror(m, Efs);
return;
}
@@ -555,7 +535,7 @@
* by one on the refcount. Adjust to
* compensate for the dup.
*/
- adec(&e->ref);
+ adec(&de->ref);
memset(&f, 0, sizeof(Fid));
f.fid = NOFID;
@@ -563,7 +543,7 @@
f.qpath = d.qid.path;
f.mode = -1;
f.iounit = iounit;
- f.dent = e;
+ f.dent = de;
if(dupfid(m->fid, &f) == nil){
rerror(m, Enomem);
return;
@@ -808,7 +788,7 @@
r.type = Rcreate;
r.qid = d.qid;
r.iounit = f->iounit;
- if((e = snapshot(f->mnt)) != nil){
+ if((e = snapshot(&f->mnt->root, f->mnt->name, 1)) != nil){
rerror(m, e);
putfid(f);
return;
@@ -850,7 +830,7 @@
runlock(f->dent);
clunkfid(f);
- if((e = snapshot(f->mnt)) != nil){
+ if((e = snapshot(&f->mnt->root, f->mnt->name, 1)) != nil){
rerror(m, e);
putfid(f);
return;
@@ -1130,7 +1110,7 @@
}
wunlock(f->dent);
- if((e = snapshot(f->mnt)) != nil){
+ if((e = snapshot(&f->mnt->root, f->mnt->name, 1)) != nil){
rerror(m, e);
putfid(f);
return;
--- a/mkfile
+++ b/mkfile
@@ -15,7 +15,6 @@
ream.$O\
sync.$O\
tree.$O\
- util.$O\
HFILES=\
dat.h\
--- a/ream.c
+++ b/ream.c
@@ -43,13 +43,23 @@
static void
initsnap(Blk *s, Blk *r)
{
- char kbuf[32], vbuf[Rootsz+Ptrsz];
+ char kbuf[Keymax], vbuf[Treesz];
Kvp kv;
+
kv.k = kbuf;
kv.v = vbuf;
- kv.k[0] = Ksnap;
+ kv.k[0] = Kdset;
kv.nk = 1 + snprint(kv.k+1, sizeof(kbuf)-1, "main");
+ kv.v[0] = Ksnap;
+ PBIT64(kv.v+1, 0);
+ kv.nv = Snapsz;
+ setval(s, 0, &kv);
+
+ kv.k[0] = Ksnap;
+ PBIT64(kv.k+1, 0);
+ kv.nk = Snapsz;
+
kv.nv = sizeof(vbuf);
PBIT32(kv.v + 0, 1);
PBIT64(kv.v + 4, r->bp.addr);
@@ -58,7 +68,7 @@
PBIT64(kv.v + 28, -1ULL);
PBIT64(kv.v + 36, -1ULL);
PBIT64(kv.v + 42, -1ULL);
- setval(s, 0, &kv);
+ setval(s, 1, &kv);
}
static void
--- a/sync.c
+++ b/sync.c
@@ -6,6 +6,19 @@
#include "dat.h"
#include "fns.h"
+vlong
+inc64(uvlong *v, uvlong dv)
+{
+ vlong ov, nv;
+
+ while(1){
+ ov = *v;
+ nv = ov + dv;
+ if(cas64(v, ov, nv))
+ return nv;
+ }
+}
+
int
syncblk(Blk *b)
{
@@ -28,23 +41,81 @@
}
}
+char*
+opensnap(Tree *t, char *name)
+{
+ char dbuf[Keymax], buf[Kvmax];
+ char *p, *e;
+ int n;
+ Key k;
+ Kvp kv;
+ n = strlen(name);
+ p = dbuf;
+ p[0] = Kdset; p += 1;
+ memcpy(p, name, n); p += n;
+ k.k = dbuf;
+ k.nk = p - dbuf;
+ if((e = btlookup(&fs->snap, &k, &kv, buf, sizeof(buf))) != nil)
+ return e;
+ memmove(dbuf, kv.v, kv.nv);
+ k.k = dbuf;
+ k.nk = kv.nv;
+ if((e = btlookup(&fs->snap, &k, &kv, buf, sizeof(buf))) != nil)
+ return e;
+ p = kv.v;
+ t->ht = GBIT32(p); p += 4;
+ t->bp.addr = GBIT64(p); p += 8;
+ t->bp.hash = GBIT64(p); p += 8;
+ t->bp.gen = GBIT64(p); p += 8;
+ t->dp.addr = GBIT64(p); p += 8;
+ t->dp.hash = GBIT64(p); p += 8;
+ t->dp.gen = GBIT64(p);
+ return nil;
+}
+
char*
-snapshot(Mount *mnt)
+snapshot(Tree *r, char *name, int update)
{
- char *e;
+ char dbuf[Keymax], snapbuf[Snapsz], treebuf[Treesz];
+ char *p, *e;
+ uvlong gen;
+ int n;
+ Msg m[2];
- mnt->m.op = Oinsert;
-// mnt->m.k[0] = Ksnap;
-// PBIT64(mnt->m.k + 1, fs->nextgen++);
- PBIT32(mnt->m.v + 0, mnt->root.ht);
- PBIT64(mnt->m.v + 4, mnt->root.bp.addr);
- PBIT64(mnt->m.v + 12, mnt->root.bp.hash);
- PBIT64(mnt->m.v + 20, mnt->root.bp.gen);
- PBIT64(mnt->m.v + 28, mnt->dead.addr);
- PBIT64(mnt->m.v + 36, mnt->dead.hash);
- PBIT64(mnt->m.v + 42, mnt->dead.gen);
- if((e = btupsert(&fs->snap, &mnt->m, 1)) != nil)
+ n = strlen(name);
+ if(update)
+ gen = inc64(&fs->nextgen, 0);
+ else
+ gen = inc64(&fs->nextgen, 1);
+
+ p = dbuf;
+ m[0].op = Oinsert;
+ p[0] = Kdset; p += 1;
+ memcpy(p, name, n); p += n;
+ m[0].k = dbuf;
+ m[0].nk = p - dbuf;
+
+ p = snapbuf;
+ p[0] = Ksnap; p += 1;
+ PBIT64(p, gen); p += 8;
+ m[0].v = snapbuf;
+ m[0].nv = p - snapbuf;
+
+ m[1].op = Oinsert;
+ m[1].k = snapbuf;
+ m[1].nk = p - snapbuf;
+ p = treebuf;
+ PBIT32(p, r->ht); p += 4;
+ PBIT64(p, r->bp.addr); p += 8;
+ PBIT64(p, r->bp.hash); p += 8;
+ PBIT64(p, r->bp.gen); p += 8;
+ PBIT64(p, r->dp.addr); p += 8;
+ PBIT64(p, r->dp.hash); p += 8;
+ PBIT64(p, r->dp.gen); p += 8;
+ m[1].v = treebuf;
+ m[1].nv = p - treebuf;
+ if((e = btupsert(&fs->snap, m, nelem(m))) != nil)
return e;
if(sync() == -1)
return Eio;
@@ -51,7 +122,6 @@
return 0;
}
-int
sync(void)
{
int i, r;
--- a/util.c
+++ /dev/null
@@ -1,41 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <fcall.h>
-#include <avl.h>
-
-#include "dat.h"
-#include "fns.h"
-
-void *
-emalloc(usize n)
-{
- void *v;
-
- v = mallocz(n, 1);
- if(v == nil)
- sysfatal("malloc: %r");
- setmalloctag(v, getcallerpc(&n));
- return v;
-}
-
-void *
-erealloc(void *p, usize n)
-{
- void *v;
-
- v = realloc(p, n);
- if(v == nil)
- sysfatal("realloc: %r");
- setmalloctag(v, getcallerpc(&n));
- return v;
-}
-
-char*
-estrdup(char *s)
-{
- s = strdup(s);
- if(s == nil)
- sysfatal("strdup: %r");
- setmalloctag(s, getcallerpc(&s));
- return s;
-}