ref: ef7604325ba923d67906222b2130f76e067b7fbb
parent: 9b157a935a17079a2ca832ce95a2e29deeca1665
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Nov 21 21:36:10 EST 2023
tree: move to kernel-style error handling
--- a/blk.c
+++ b/blk.c
@@ -47,13 +47,14 @@
}
}
-int
+void
syncblk(Blk *b)
{
assert(checkflag(b, Bfinal));
assert(b->bp.addr >= 0);
clrflag(b, Bdirty);
- return pwrite(fs->fd, b->buf, Blksz, b->bp.addr);
+ if(pwrite(fs->fd, b->buf, Blksz, b->bp.addr) == -1)
+ broke("%r");
}
static Blk*
@@ -71,10 +72,8 @@
rem = Blksz;
while(rem != 0){
n = pread(fs->fd, b->buf, rem, off);
- if(n <= 0){
- dropblk(b);
- return nil;
- }
+ if(n <= 0)
+ error("%r");
off += n;
rem -= n;
}
@@ -98,8 +97,7 @@
b->type = (flg&GBraw) ? Tdat : UNPACK16(b->buf+0);
switch(b->type){
default:
- fprint(2, "invalid block type %d @%llx\n", b->type, bp);
- return nil;
+ broke("invalid block type %d @%llx\n", b->type, bp);
break;
case Tdat:
case Tsuper:
@@ -243,8 +241,7 @@
cachedel(lb->bp.addr);
initblk(lb, o, -1, Tlog);
finalize(lb);
- if(syncblk(lb) == -1)
- return nil;
+ syncblk(lb);
return lb;
}
@@ -296,10 +293,7 @@
lb->logp = nl->bp;
setflag(lb, Bdirty);
finalize(lb);
- if(syncblk(lb) == -1){
- fs->broken = 1;
- return -1;
- }
+ syncblk(lb);
a->logtl = nl;
a->nlog++;
lb = nl;
@@ -508,10 +502,8 @@
r = (Arange*)t->root;
if(!force && a->size - a->used <= a->reserve)
return -1;
- if(r == nil){
- fprint(2, "out of space");
- abort();
- }
+ if(r == nil)
+ broke(Efull);
/*
* A bit of sleight of hand here:
@@ -537,8 +529,6 @@
int r;
r = -1;
-assert(b >= a->hd->bp.addr + Blksz);
-assert(b < a->tl->bp.addr);
if(logappend(a, b, Blksz, LogFree) == -1)
return -1;
if(a->loghd.addr == -1)
@@ -593,8 +583,13 @@
tries++;
if(canqlock(a) == 0)
goto Again;
+ if(waserror()){
+ qunlock(a);
+ nexterror();
+ }
if((b = blkalloc_lk(a, 0)) == -1){
qunlock(a);
+ poperror();
goto Again;
}
if(logappend(a, b, Blksz, LogAlloc) == -1){
@@ -604,6 +599,7 @@
if(a->loghd.addr == -1)
a->loghd = a->logtl->bp;
qunlock(a);
+ poperror();
return b;
}
@@ -613,11 +609,8 @@
Blk *ob;
ob = cacheget(bp);
- if(ob != nil){
- fprint(2, "dup block: %#p %B (azoced %#zx freed %#zx lasthold: %#zx, lastdrop: %#zx)\n",
- ob, ob->bp, ob->alloced, ob->freed, ob->lasthold, ob->lastdrop);
- abort();
- }
+ if(ob != nil)
+ fatal("double alloc: %#p %B %#p %B", b, b->bp, ob, ob->bp);
b->type = ty;
b->bp.addr = bp;
b->bp.hash = -1;
@@ -748,11 +741,7 @@
qunlock(&fs->blklk[i]);
return b;
}
- if((b = readblk(bp.addr, flg)) == nil){
- fprint(2, "could not read %B\n", bp);
- qunlock(&fs->blklk[i]);
- return nil;
- }
+ b = readblk(bp.addr, flg);
b->alloced = getcallerpc(&bp);
b->bp.hash = blkhash(b);
if((flg&GBnochk) == 0){
@@ -1084,11 +1073,7 @@
qunlock(&fs->synclk);
}else{
if(checkflag(qe.b, Bfreed) == 0)
- if(syncblk(qe.b) == -1){
- ainc(&fs->broken);
- fprint(2, "write: %r\n");
- abort();
- }
+ syncblk(qe.b);
dropblk(qe.b);
}
}
@@ -1102,11 +1087,17 @@
Qent qe;
int i;
+ if(waserror()){
+ fprint(2, "failed to sync: %s\n", errmsg());
+ nexterror();
+ }
+
if(fs->rdonly)
return;
qlock(&fs->synclk);
if(!fs->snap.dirty){
qunlock(&fs->synclk);
+ poperror();
return;
}
flushdlcache(0);
@@ -1128,8 +1119,7 @@
qlock(a);
syncbarrier(a, gen);
finalize(a->logtl);
- if(syncblk(a->logtl) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->logtl);
qunlock(a);
}
/*
@@ -1142,8 +1132,7 @@
qlock(a);
packarena(a->hd->data, Blksz, a);
finalize(a->hd);
- if(syncblk(a->hd) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->hd);
qunlock(a);
}
/*
@@ -1159,10 +1148,8 @@
packsb(fs->sb1->buf, Blksz, fs);
finalize(fs->sb0);
finalize(fs->sb1);
- if(syncblk(fs->sb0) == -1)
- sysfatal("sync sb: %r");
- if(syncblk(fs->sb1) == -1)
- sysfatal("sync sb: %r");
+ syncblk(fs->sb0);
+ syncblk(fs->sb1);
fs->snap.dirty = 0;
/*
* pass 3: sync block footers; if we crash here,
@@ -1174,8 +1161,7 @@
qlock(a);
packarena(a->tl->data, Blksz, a);
finalize(a->tl);
- if(syncblk(a->tl) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->tl);
qunlock(a);
}
/*
@@ -1190,4 +1176,5 @@
fs->snapdl.tl.gen = -1;
fs->snapdl.ins = nil;
qunlock(&fs->synclk);
+ poperror();
}
--- a/dat.h
+++ b/dat.h
@@ -1,6 +1,7 @@
typedef struct Blk Blk;
typedef struct Amsg Amsg;
typedef struct Gefs Gefs;
+typedef struct Errctx Errctx;
typedef struct Fmsg Fmsg;
typedef struct Fid Fid;
typedef struct Msg Msg;
@@ -79,7 +80,8 @@
Logspc = Blksz - Loghdsz,
Logslop = 16+16+8, /* val, nextb, chain */
Leafspc = Blksz - Leafhdsz,
- Msgmax = 1 + (Kvmax > Kpmax ? Kvmax : Kpmax)
+ Msgmax = 1 + (Kvmax > Kpmax ? Kvmax : Kpmax),
+ Estacksz = 64,
};
enum {
@@ -358,6 +360,12 @@
Bptr tl; /* deadlist tail */
};
+struct Errctx {
+ char err[128];
+ jmp_buf errlab[Estacksz];
+ int nerrlab;
+};
+
struct Arange {
Avl;
vlong off;
@@ -523,7 +531,6 @@
int fd;
- long broken;
long rdonly;
int noauth;
--- a/fns.h
+++ b/fns.h
@@ -11,6 +11,7 @@
extern int debug;
extern int permissive;
extern char* reamuser;
+extern void** errctx;
extern Blk* blkbuf;
#define UNPACK8(p) (((uchar*)(p))[0])
@@ -47,7 +48,7 @@
void qput(Syncq*, Qent);
Arena* getarena(vlong);
-int syncblk(Blk*);
+void syncblk(Blk*);
void enqueue(Blk*);
void epochstart(int);
void epochend(int);
@@ -137,6 +138,15 @@
fprint(2, __VA_ARGS__); \
abort(); \
}while(0)
+
+jmp_buf* _waserror(void);
+_Noreturn void errorv(char*, va_list);
+_Noreturn void error(char*, ...);
+_Noreturn void broke(char*, ...);
+_Noreturn void nexterror(void);
+#define waserror() (setjmp(*_waserror()))
+#define errmsg() (((Errctx*)*errctx)->err)
+#define poperror() (((Errctx*)*errctx)->nerrlab--)
char* pack8(int*, char*, char*, uchar);
char* pack16(int*, char*, char*, ushort);
--- a/fs.c
+++ b/fs.c
@@ -2198,10 +2198,6 @@
rerror(m, Erdonly);
continue;
}
- if(fs->broken){
- rerror(m, Efs);
- continue;
- }
qlock(&fs->mutlk);
epochstart(id);
@@ -2350,11 +2346,8 @@
for(i = 0; i < fs->narena; i++){
for(bp = oldhd[i]; bp.addr != -1; bp = nb){
epochstart(id);
- if((b = getblk(bp, 0)) == nil){
- fprint(2, "could not load %B\n", bp);
- fs->broken = 1;
- break;
- }
+ if((b = getblk(bp, 0)) == nil)
+ broke("reading %B: %s", bp, errmsg());
nb = b->logp;
freeblk(nil, b, b->bp);
dropblk(b);
@@ -2393,10 +2386,8 @@
PACK64(m.k+9, off);
m.v = nil;
m.nv = 0;
- if((e = upsert(am->mnt, &m, 1)) != nil){
- fprint(2, "sweep: %s\n", e);
- fs->broken++;
- }
+ if((e = upsert(am->mnt, &m, 1)) != nil)
+ broke("reading %B: %s", bp, e);
epochend(id);
qunlock(&fs->mutlk);
epochclean();
--- a/main.c
+++ b/main.c
@@ -21,7 +21,63 @@
char *dev;
vlong cachesz = 512*MiB;
Blk *blkbuf;
+void **errctx;
+jmp_buf*
+_waserror(void)
+{
+ Errctx *c;
+
+ c = *errctx;
+ c->nerrlab++;
+if(c->nerrlab >= Estacksz)
+for(int i = 0; i < Estacksz; i++) print("%zx %zx\n", c->errlab[i][0], c->errlab[i][1]);
+ assert(c->nerrlab > 0 && c->nerrlab < Estacksz);
+ return c->errlab + (c->nerrlab-1);
+}
+
+_Noreturn void
+errorv(char *fmt, va_list ap)
+{
+ Errctx *c;
+
+ c = *errctx;
+ vsnprint(c->err, sizeof(c->err), fmt, ap);
+ assert(c->nerrlab > 0 && c->nerrlab < Estacksz);
+ longjmp(c->errlab[--c->nerrlab], -1);
+}
+
+_Noreturn void
+broke(char *fmt, ...)
+{
+ va_list ap;
+
+ aincl(&fs->rdonly, 1);
+ va_start(ap, fmt);
+ vfprint(2, fmt, ap);
+ errorv(fmt, ap);
+}
+
+_Noreturn void
+error(char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ errorv(fmt, ap);
+}
+
+
+_Noreturn void
+nexterror(void)
+{
+ Errctx *c;
+
+ c = *errctx;
+ assert(c->nerrlab > 0 && c->nerrlab < Estacksz);
+ longjmp(c->errlab[--c->nerrlab], -1);
+}
+
static void
initfs(vlong cachesz)
{
@@ -68,6 +124,8 @@
sysfatal("can't fork: %r");
if (pid == 0) {
id = aincl(&fs->nworker, 1);
+ if((*errctx = mallocz(sizeof(Errctx), 1)) == nil)
+ sysfatal("malloc: %r");
procsetname("%s.%ld", text, id);
(*f)(id, arg);
exits("child returned");
@@ -194,6 +252,9 @@
initfs(cachesz);
initshow();
+ errctx = privalloc();
+ if((*errctx = mallocz(sizeof(Errctx), 1)) == nil)
+ sysfatal("malloc: %r");
fmtinstall('H', encodefmt);
fmtinstall('B', Bconv);
fmtinstall('M', Mconv);
--- a/ream.c
+++ b/ream.c
@@ -213,8 +213,7 @@
PACK64(p, (uvlong)LogSync); p += 8; /* barrier */
b->logsz = p - b->data;
finalize(b);
- if(syncblk(b) == -1)
- sysfatal("ream: init log");
+ syncblk(b);
dropblk(b);
bh = b->bp.hash;
@@ -245,10 +244,8 @@
packarena(tl->data, Arenasz, a);
finalize(hd);
finalize(tl);
- if(syncblk(hd) == -1)
- sysfatal("ream: write arena: %r");
- if(syncblk(tl) == -1)
- sysfatal("ream: write arena: %r");
+ syncblk(hd);
+ syncblk(tl);
a->hd = hd;
a->tl = tl;
}
@@ -263,6 +260,8 @@
Dir *d;
int i;
+ if(waserror())
+ sysfatal("ream %s: %s\n", dev, errmsg());
if((fs->fd = open(dev, ORDWR)) == -1)
sysfatal("open %s: %r", dev);
if((d = dirfstat(fs->fd)) == nil)
@@ -385,16 +384,13 @@
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
finalize(a->logtl);
- if(syncblk(a->logtl) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->logtl);
packarena(a->hd->data, Blksz, a);
finalize(a->hd);
- if(syncblk(a->hd) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->hd);
packarena(a->tl->data, Blksz, a);
finalize(a->tl);
- if(syncblk(a->tl) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->tl);
fs->arenabp[i] = a->hd->bp;
dropblk(a->hd);
dropblk(a->tl);
@@ -413,14 +409,12 @@
packsb(sb1->buf, Blksz, fs);
finalize(sb0);
finalize(sb1);
- if(syncblk(sb0) == -1)
- sysfatal("sync superblock: %r");
- if(syncblk(sb1) == -1)
- sysfatal("sync superblock: %r");
+ syncblk(sb0);
+ syncblk(sb1);
dropblk(sb0);
dropblk(sb1);
-
free(mnt);
+ poperror();
}
void
@@ -432,6 +426,8 @@
Arena *a;
Dir *d;
+ if(waserror())
+ sysfatal("grow %s: %s\n", dev, errmsg());
if((fs->fd = open(dev, ORDWR)) == -1)
sysfatal("open %s: %r", dev);
if((d = dirfstat(fs->fd)) == nil)
@@ -475,17 +471,14 @@
packarena(a->tl->data, Blksz, a);
finalize(a->hd);
finalize(a->tl);
- if(syncblk(a->hd) == -1)
- sysfatal("sync arena: %r");
- if(syncblk(a->tl) == -1)
- sysfatal("sync arena: %r");
+ syncblk(a->hd);
+ syncblk(a->tl);
}
packsb(fs->sb0->buf, Blksz, fs);
packsb(fs->sb1->buf, Blksz, fs);
finalize(fs->sb0);
finalize(fs->sb1);
- if(syncblk(fs->sb0) == -1)
- sysfatal("sync superblock: %r");
- if(syncblk(fs->sb1) == -1)
- sysfatal("sync superblock: %r");
+ syncblk(fs->sb0);
+ syncblk(fs->sb1);
+ poperror();
}
--- a/tree.c
+++ b/tree.c
@@ -27,6 +27,11 @@
int pullsz; /* size of pulled messages */
};
+#define efreeblk(t, b) do { \
+ if(b != nil) \
+ freeblk(t, b, b->bp); \
+ } while(0)
+
static void
stablesort(Msg *m, int nm)
{
@@ -454,7 +459,7 @@
*
* When pidx != -1,
*/
-static int
+static void
updateleaf(Tree *t, Path *up, Path *p)
{
char buf[Msgmax];
@@ -477,8 +482,7 @@
*/
full = 0;
spc = Leafspc - blkfill(b);
- if((n = newblk(t, b->type)) == nil)
- return -1;
+ n = newblk(t, b->type);
assert(i >= 0 && j >= 0);
while(i < b->nval){
ok = 1;
@@ -550,7 +554,6 @@
}
p->npull = (j - up->lo);
p->nl = n;
- return 0;
}
/*
@@ -561,7 +564,7 @@
*
* When pidx != -1,
*/
-static int
+static void
updatepiv(Tree *t, Path *up, Path *p, Path *pp)
{
char buf[Msgmax];
@@ -570,8 +573,7 @@
Msg m, u;
b = p->b;
- if((n = newblk(t, b->type)) == nil)
- return -1;
+ n = newblk(t, b->type);
for(i = 0; i < b->nval; i++){
if(pp != nil && i == p->midx){
copyup(n, pp, nil);
@@ -624,7 +626,6 @@
}
p->npull = (j - up->lo);
p->nl = n;
- return 0;
}
/*
@@ -632,7 +633,7 @@
* would be inserted into. Split must never
* grow the total height of the tree by more than 1.
*/
-static int
+static void
splitleaf(Tree *t, Path *up, Path *p, Kvp *mid)
{
char buf[Msgmax];
@@ -648,13 +649,15 @@
* so we want to make a new block.
*/
b = p->b;
+ l = nil;
+ r = nil;
+ if(waserror()){
+ efreeblk(t, l);
+ efreeblk(t, r);
+ return;
+ }
l = newblk(t, b->type);
r = newblk(t, b->type);
- if(l == nil || r == nil){
- freeblk(t, l, l->bp);
- freeblk(t, r, r->bp);
- return -1;
- }
d = l;
i = 0;
@@ -721,8 +724,7 @@
p->op = POsplit;
p->nl = l;
p->nr = r;
-
- return 0;
+ poperror();
}
/*
@@ -731,7 +733,7 @@
* grow the total height of the tree by more
* than one.
*/
-static int
+static void
splitpiv(Tree *t, Path *, Path *p, Path *pp, Kvp *mid)
{
int i, copied, halfsz;
@@ -745,13 +747,15 @@
* so we want to make a new bp->lock.
*/
b = p->b;
+ l = nil;
+ r = nil;
+ if(waserror()){
+ efreeblk(t, l);
+ efreeblk(t, r);
+ return;
+ }
l = newblk(t, b->type);
r = newblk(t, b->type);
- if(l == nil || r == nil){
- freeblk(t, l, l->bp);
- freeblk(t, r, r->bp);
- return -1;
- }
d = l;
copied = 0;
halfsz = (2*b->nval + b->valsz)/2;
@@ -790,11 +794,9 @@
p->op = POsplit;
p->nl = l;
p->nr = r;
-
- return 0;
}
-static int
+static void
merge(Tree *t, Path *p, Path *pp, int idx, Blk *a, Blk *b)
{
Blk *d;
@@ -801,8 +803,7 @@
Msg m;
int i;
- if((d = newblk(t, a->type)) == nil)
- return -1;
+ d = newblk(t, a->type);
for(i = 0; i < a->nval; i++){
getval(a, i, &m);
setval(d, &m);
@@ -826,7 +827,6 @@
pp->nl = d;
pp->op = POmerge;
pp->nr = nil;
- return 0;
}
/*
@@ -873,7 +873,7 @@
return 0;
}
-static int
+static void
rotate(Tree *t, Path *p, Path *pp, int midx, Blk *a, Blk *b, int halfpiv)
{
int i, o, cp, sp, idx;
@@ -880,13 +880,15 @@
Blk *d, *l, *r;
Msg m;
+ l = nil;
+ r = nil;
+ if(waserror()){
+ efreeblk(t, l);
+ efreeblk(t, r);
+ return;
+ }
l = newblk(t, a->type);
r = newblk(t, a->type);
- if(l == nil || r == nil){
- freeblk(t, l, l->bp);
- freeblk(t, r, r->bp);
- return -1;
- }
d = l;
cp = 0;
sp = -1;
@@ -937,10 +939,10 @@
pp->op = POrot;
pp->nl = l;
pp->nr = r;
- return 0;
+ poperror();
}
-static int
+static void
rotmerge(Tree *t, Path *p, Path *pp, int idx, Blk *a, Blk *b)
{
int na, nb, ma, mb, imbalance;
@@ -961,39 +963,40 @@
imbalance *= -1;
/* works for leaf, because 0 always < Bufspc */
if(na + nb < (Pivspc - 4*Msgmax) && ma + mb < Bufspc)
- return merge(t, p, pp, idx, a, b);
+ merge(t, p, pp, idx, a, b);
else if(imbalance > 4*Msgmax)
- return rotate(t, p, pp, idx, a, b, (na + nb)/2);
- else
- return 0;
+ rotate(t, p, pp, idx, a, b, (na + nb)/2);
}
-static int
+static void
trybalance(Tree *t, Path *p, Path *pp, int idx)
{
Blk *l, *m, *r;
Kvp kl, kr;
- int spc, ret, fill;
+ int spc, fill;
Bptr bp;
- l = nil;
- r = nil;
- ret = -1;
if(p->idx == -1 || pp == nil || pp->nl == nil)
- return 0;
+ return;
if(pp->op != POmod || pp->op != POmerge)
- return 0;
+ return;
+ l = nil;
+ r = nil;
m = holdblk(pp->nl);
+ if(waserror()){
+ dropblk(m);
+ dropblk(l);
+ dropblk(r);
+ nexterror();
+ }
spc = (m->type == Tleaf) ? Leafspc : Pivspc;
if(idx-1 >= 0){
getval(p->b, idx-1, &kl);
bp = getptr(&kl, &fill);
if(fill + blkfill(m) < spc){
- if((l = getblk(bp, 0)) == nil)
- goto Out;
- if(rotmerge(t, p, pp, idx-1, l, m) == -1)
- goto Out;
+ l = getblk(bp, 0);
+ rotmerge(t, p, pp, idx-1, l, m);
goto Done;
}
}
@@ -1001,20 +1004,16 @@
getval(p->b, idx+1, &kr);
bp = getptr(&kr, &fill);
if(fill + blkfill(m) < spc){
- if((r = getblk(bp, 0)) == nil)
- goto Out;
- if(rotmerge(t, p, pp, idx, m, r) == -1)
- goto Out;
+ r = getblk(bp, 0);
+ rotmerge(t, p, pp, idx, m, r);
goto Done;
}
}
Done:
- ret = 0;
-Out:
dropblk(m);
dropblk(l);
dropblk(r);
- return ret;
+ poperror();
}
static Path*
@@ -1037,14 +1036,12 @@
up = &path[npath - 2];
if(p->b->type == Tleaf){
if(!filledleaf(p->b, up->sz)){
- if(updateleaf(t, p-1, p) == -1)
- goto Error;
+ updateleaf(t, p-1, p);
enqueue(p->nl);
rp = p;
}else{
- if(splitleaf(t, up, p, &mid) == -1)
- goto Error;
+ splitleaf(t, up, p, &mid);
enqueue(p->nl);
enqueue(p->nr);
}
@@ -1055,20 +1052,17 @@
}
while(p != path){
if(!filledpiv(p->b, 1)){
- if(trybalance(t, p, pp, p->idx) == -1)
- goto Error;
+ trybalance(t, p, pp, p->idx);
/* If we merged the root node, break out. */
if(up == path && pp != nil && pp->op == POmerge && p->b->nval == 2){
rp = pp;
goto Out;
}
- if(updatepiv(t, up, p, pp) == -1)
- goto Error;
+ updatepiv(t, up, p, pp);
enqueue(p->nl);
rp = p;
}else{
- if(splitpiv(t, up, p, pp, &mid) == -1)
- goto Error;
+ splitpiv(t, up, p, pp, &mid);
enqueue(p->nl);
enqueue(p->nr);
}
@@ -1079,8 +1073,6 @@
if(pp->nl != nil && pp->nr != nil){
rp = &path[0];
rp->nl = newblk(t, Tpivot);
- if(rp->nl == nil)
- goto Error;
rp->npull = pp->npull;
rp->pullsz = pp->pullsz;
copyup(rp->nl, pp, nil);
@@ -1088,8 +1080,6 @@
}
Out:
return rp;
-Error:
- return nil;
}
static void
@@ -1154,7 +1144,7 @@
}
}
-static char*
+static void
fastupsert(Tree *t, Blk *b, Msg *msg, int nmsg)
{
int i, c, o, ri, lo, hi, mid, nbuf;
@@ -1163,7 +1153,7 @@
Blk *r;
if((r = dupblk(t, b)) == nil)
- return Enomem;
+ error(Enomem);
nbuf = r->nbuf;
for(i = 0; i < nmsg; i++)
@@ -1208,7 +1198,6 @@
freeblk(t, b, b->bp);
dropblk(b);
dropblk(r);
- return nil;
}
@@ -1226,12 +1215,20 @@
for(i = 0; i < nmsg; i++)
sz += msgsz(&msg[i]);
npull = 0;
+ path = nil;
+ npath = 0;
+ if(waserror()){
+ freepath(t, path, npath);
+ return errmsg();
+ }
Again:
- if((b = getroot(t, &height)) == nil)
- return Efs;
- if(b->type == Tpivot && !filledbuf(b, nmsg, sz))
- return fastupsert(t, b, msg, nmsg);
+ b = getroot(t, &height);
+ if(b->type == Tpivot && !filledbuf(b, nmsg, sz)){
+ fastupsert(t, b, msg, nmsg);
+ poperror();
+ return nil;
+ }
/*
* The tree can grow in height by 1 when we
@@ -1257,8 +1254,6 @@
getval(b, path[npath].idx, &sep);
bp = unpackbp(sep.v, sep.nv);
b = getblk(bp, 0);
- if(b == nil)
- goto Error;
npath++;
}
path[npath].b = b;
@@ -1272,8 +1267,6 @@
dh = -1;
rp = flush(t, path, npath);
- if(rp == nil)
- goto Error;
rb = rp->nl;
if(path[0].nl != nil)
@@ -1298,10 +1291,8 @@
freepath(t, path, npath);
if(npull != nmsg)
goto Again;
- return 0;
-Error:
- freepath(t, path, npath);
- return Efs;
+ poperror();
+ return nil;
}
Blk*