ref: 95332069fecfe2e7497b21dad8c06f1b93cb1d40
parent: 97700c98f4d56d8fafff628fb9356bab8cb1b5f3
author: Ori Bernstein <[email protected]>
date: Wed Nov 22 11:56:57 EST 2023
all: more error cleanup
--- a/blk.c
+++ b/blk.c
@@ -9,7 +9,7 @@
static vlong blkalloc_lk(Arena*, int);
static vlong blkalloc(int, uint);
-static int blkdealloc_lk(Arena*, vlong);
+static void blkdealloc_lk(Arena*, vlong);
static Blk* initblk(Blk*, vlong, vlong, int);
int
@@ -54,7 +54,7 @@
assert(b->bp.addr >= 0);
clrflag(b, Bdirty);
if(pwrite(fs->fd, b->buf, Blksz, b->bp.addr) == -1)
- broke("%r");
+ broke("%s: %r", Eio);
}
static Blk*
@@ -65,8 +65,7 @@
Blk *b;
assert(bp != -1);
- if((b = cachepluck()) == nil)
- return nil;
+ b = cachepluck();
b->alloced = getcallerpc(&bp);
off = bp;
rem = Blksz;
@@ -73,7 +72,7 @@
while(rem != 0){
n = pread(fs->fd, b->buf, rem, off);
if(n <= 0)
- error("%r");
+ error("%s: %r", Eio);
off += n;
rem -= n;
}
@@ -160,7 +159,7 @@
return &fs->arenas[i];
}
-static int
+static void
freerange(Avltree *t, vlong off, vlong len)
{
Arange *r, *s;
@@ -167,7 +166,7 @@
assert(len % Blksz == 0);
if((r = calloc(1, sizeof(Arange))) == nil)
- return -1;
+ error(Enomem);
r->off = off;
r->len = len;
assert(avllookup(t, r, 0) == nil);
@@ -174,7 +173,6 @@
avlinsert(t, r);
Again:
-
s = (Arange*)avlprev(r);
if(s != nil && s->off+s->len == r->off){
avldelete(t, r);
@@ -192,10 +190,9 @@
r = s;
goto Again;
}
- return 0;
}
-static int
+static void
grabrange(Avltree *t, vlong off, vlong len)
{
Arange *r, *s, q;
@@ -214,8 +211,7 @@
}else if(off + len == r->off + r->len){
r->len -= len;
}else if(off > r->off && off+len < r->off + r->len){
- if((s = malloc(sizeof(Arange))) == nil)
- return -1;
+ s = emalloc(sizeof(Arange), 0);
l = r->len;
s->off = off + len;
r->len = off - r->off;
@@ -228,7 +224,6 @@
avldelete(t, r);
free(r);
}
- return 0;
}
static Blk*
@@ -251,7 +246,7 @@
* of the work in allocblk to prevent
* recursion.
*/
-static int
+static void
logappend(Arena *a, vlong off, vlong len, int op)
{
vlong o;
@@ -283,10 +278,8 @@
* and chaining.
*/
if(lb == nil || lb->logsz >= Logspc - Logslop){
- if((o = blkalloc_lk(a, 1)) == -1)
- return -1;
- if((nl = mklogblk(a, o)) == nil)
- return -1;
+ o = blkalloc_lk(a, 1);
+ nl = mklogblk(a, o);
p = lb->data + lb->logsz;
PACK64(p, o|LogAlloc1);
lb->logsz += 8;
@@ -314,10 +307,9 @@
PACK64(p+8, len);
lb->logsz += 8;
}
- return 0;
}
-int
+void
loadlog(Arena *a, Bptr bp)
{
vlong ent, off, len, gen;
@@ -328,8 +320,7 @@
dprint("loadlog %B\n", bp);
while(1){
- if((b = getblk(bp, 0)) == nil)
- return -1;
+ b = getblk(bp, 0);
dprint("\tload %B chain %B\n", bp, b->logp);
/* the hash covers the log and offset */
for(i = 0; i < b->logsz; i += n){
@@ -346,10 +337,10 @@
if(a->logtl == nil){
b->logsz = i;
a->logtl = holdblk(b);
- return 0;
+ return;
}
dropblk(b);
- return 0;
+ return;
}
break;
@@ -357,8 +348,7 @@
case LogAlloc1:
len = (op >= Log2wide) ? UNPACK64(d+8) : Blksz;
dprint("\tlog@%d alloc: %llx+%llx\n", i, off, len);
- if(grabrange(a->free, off & ~0xff, len) == -1)
- return -1;
+ grabrange(a->free, off & ~0xff, len);
a->used += len;
break;
case LogFree:
@@ -365,10 +355,7 @@
case LogFree1:
len = (op >= Log2wide) ? UNPACK64(d+8) : Blksz;
dprint("\tlog@%d free: %llx+%llx\n", i, off, len);
- if(freerange(a->free, off & ~0xff, len) == -1){
- werrstr("invalid free: %r");
- return -1;
- }
+ freerange(a->free, off & ~0xff, len);
a->used -= len;
break;
default:
@@ -380,7 +367,7 @@
}
if(b->logp.addr == -1){
a->logtl = b;
- return 0;
+ return;
}
bp = b->logp;
dropblk(b);
@@ -426,17 +413,17 @@
nblks = (sz+Logspc)/(Logspc - Logslop) + 16*nr/(Logspc-Logslop) + 1;
if((blks = calloc(nblks, sizeof(vlong))) == nil)
return -1;
- for(i = 0; i < nblks; i++){
- blks[i] = blkalloc_lk(a, 1);
- if(blks[i] == -1)
- return -1;
+ if(waserror()){
+ free(blks);
+ return -1;
}
+ for(i = 0; i < nblks; i++)
+ blks[i] = blkalloc_lk(a, 1);
/* fill up the log with the ranges from the tree */
i = 0;
hd = (Bptr){blks[0], -1, -1};
- if((b = cachepluck()) == nil)
- return -1;
+ b = cachepluck();
initblk(b, blks[i++], -1, Tlog);
for(r = (Arange*)avlmin(a->free); r != nil; r = (Arange*)avlnext(r)){
if(b->logsz >= Logspc - Logslop){
@@ -472,6 +459,7 @@
cachedel(b->bp.addr);
blkdealloc_lk(a, blks[i]);
}
+ free(blks);
return 0;
}
@@ -478,8 +466,7 @@
int
syncbarrier(Arena *a, vlong gen)
{
- if(logappend(a, gen<<8, 0, LogSync) == -1)
- return -1;
+ logappend(a, gen<<8, 0, LogSync);
if(a->loghd.addr == -1)
a->loghd = a->logtl->bp;
return 0;
@@ -503,7 +490,7 @@
if(!force && a->size - a->used <= a->reserve)
return -1;
if(r == nil)
- broke(Efull);
+ broke(Estuffed);
/*
* A bit of sleight of hand here:
@@ -523,35 +510,25 @@
return b;
}
-static int
+static void
blkdealloc_lk(Arena *a, vlong b)
{
- int r;
-
- r = -1;
- if(logappend(a, b, Blksz, LogFree) == -1)
- return -1;
+ logappend(a, b, Blksz, LogFree);
if(a->loghd.addr == -1)
a->loghd = a->logtl->bp;
- if(freerange(a->free, b, Blksz) == -1)
- goto out;
+ freerange(a->free, b, Blksz);
a->used -= Blksz;
- r = 0;
-out:
- return r;
}
-int
+void
blkdealloc(vlong b)
{
Arena *a;
- int r;
a = getarena(b);
qlock(a);
- r = blkdealloc_lk(a, b);
+ blkdealloc_lk(a, b);
qunlock(a);
- return r;
}
static vlong
@@ -592,10 +569,7 @@
poperror();
goto Again;
}
- if(logappend(a, b, Blksz, LogAlloc) == -1){
- qunlock(a);
- return -1;
- }
+ logappend(a, b, Blksz, LogAlloc);
if(a->loghd.addr == -1)
a->loghd = a->logtl->bp;
qunlock(a);
@@ -647,15 +621,13 @@
}
Blk*
-newdblk(Tree *t, int ty, vlong hint)
+newblk(Tree *t, int ty, vlong hint)
{
vlong bp;
Blk *b;
- if((bp = blkalloc(ty, hint)) == -1)
- return nil;
- if((b = cachepluck()) == nil)
- return nil;
+ bp = blkalloc(ty, hint);
+ b = cachepluck();
initblk(b, bp, t->memgen, ty);
b->alloced = getcallerpc(&t);
return b;
@@ -662,17 +634,11 @@
}
Blk*
-newblk(Tree *t, int ty)
-{
- return newdblk(t, ty, 0);
-}
-
-Blk*
dupblk(Tree *t, Blk *b)
{
Blk *r;
- if((r = newblk(t, b->type)) == nil)
+ if((r = newblk(t, b->type, 0)) == nil)
return nil;
setflag(r, Bdirty);
@@ -730,14 +696,18 @@
getblk(Bptr bp, int flg)
{
uvlong xh, ck;
- char *t;
Blk *b;
int i;
i = ihash(bp.addr) % nelem(fs->blklk);
qlock(&fs->blklk[i]);
+ if(waserror()){
+ qunlock(&fs->blklk[i]);
+ nexterror();
+ }
if((b = cacheget(bp.addr)) != nil){
b->lasthold = getcallerpc(&bp);
+ poperror();
qunlock(&fs->blklk[i]);
return b;
}
@@ -746,24 +716,19 @@
b->bp.hash = blkhash(b);
if((flg&GBnochk) == 0){
if(b->type == Tlog || b->type == Tdlist){
- t = "log";
xh = b->logh;
ck = bufhash(b->data, b->logsz);
}else{
- t = "block";
xh = bp.hash;
ck = b->bp.hash;
}
- if(ck != xh){
- fprint(2, "corrupt %s %p %B: %.16llux != %.16llux\n",
- t, b, bp, xh, ck);
- qunlock(&fs->blklk[i]);
- return nil;
- }
+ if(ck != xh)
+ error("%s: %llx != %llx", Ecorrupt, xh, ck);
}
b->bp.gen = bp.gen;
b->lasthold = getcallerpc(&bp);
cacheins(b);
+ poperror();
qunlock(&fs->blklk[i]);
return b;
@@ -837,8 +802,7 @@
return;
}
- if((f = malloc(sizeof(Bfree))) == nil)
- abort();
+ f = emalloc(sizeof(Bfree), 0);
f->op = DFblk;
f->bp = bp;
f->b = nil;
@@ -966,8 +930,7 @@
q->emptyrz.l = &q->lk;
q->nheap = 0;
q->heapsz = fs->cmax;
- if((q->heap = malloc(q->heapsz*sizeof(Qent))) == nil)
- sysfatal("alloc queue: %r");
+ q->heap = emalloc(q->heapsz*sizeof(Qent), 1);
}
--- a/dat.h
+++ b/dat.h
@@ -132,6 +132,8 @@
/* internal errors */
#define Efs (abort(), "fs broke")
+extern char Ecorrupt[];
+extern char Efsvers[];
extern char Eimpl[];
extern char Ebotch[];
extern char Eio[];
@@ -143,6 +145,7 @@
extern char Eexist[];
extern char Emode[];
extern char Efull[];
+extern char Estuffed[];
extern char Eauth[];
extern char Elength[];
extern char Eperm[];
--- a/dump.c
+++ b/dump.c
@@ -82,12 +82,10 @@
switch(op){
case Onop:
case Oinsert:
- if(kv2dir(v, &d) == -1)
- n = fmtprint(fmt, "bad dir");
- else
- n = fmtprint(fmt, "[qid=(%llux,%lud,%d), %luo, t=%lld,%lld, l=%lld]",
- d.qid.path, d.qid.vers, d.qid.type,
- d.mode, d.atime, d.mtime, d.length);
+ kv2dir(v, &d);
+ n = fmtprint(fmt, "[qid=(%llux,%lud,%d), %luo, t=%lld,%lld, l=%lld]",
+ d.qid.path, d.qid.vers, d.qid.type,
+ d.mode, d.atime, d.mtime, d.length);
break;
case Odelete:
n = fmtprint(fmt, "delete");
--- a/error.c
+++ b/error.c
@@ -4,6 +4,8 @@
#include <fcall.h>
#include "dat.h"
+char Ecorrupt[] = "block contents corrupted";
+char Efsvers[] = "unknown fs version";
char Eimpl[] = "not implemented";
char Ebotch[] = "protocol botch";
char Eio[] = "i/o error";
@@ -15,6 +17,7 @@
char Eexist[] = "create/wstat -- file exists";
char Emode[] = "open/create -- unknown mode";
char Efull[] = "file system full";
+char Estuffed[] = "emergency blocks exhausted";
char Eauth[] = "authentication failed";
char Elength[] = "name too long";
char Eperm[] = "permission denied";
--- a/fns.h
+++ b/fns.h
@@ -13,6 +13,8 @@
extern char* reamuser;
extern void** errctx;
extern Blk* blkbuf;
+extern int noneid;
+extern int nogroupid;
#define UNPACK8(p) (((uchar*)(p))[0])
#define UNPACK16(p) ((((uchar*)(p))[0]<<8)|(((uchar*)(p))[1]))
@@ -29,8 +31,9 @@
#define PACK64(p,v) do{(p)[0]=(v)>>56;(p)[1]=(v)>>48;(p)[2]=(v)>>40;(p)[3]=(v)>>32;\
(p)[4]=(v)>>24;(p)[5]=(v)>>16;(p)[6]=(v)>>8;(p)[7]=(v);}while(0)
-Blk* newdblk(Tree *, int, vlong);
-Blk* newblk(Tree *, int);
+void* emalloc(usize, int);
+
+Blk* newblk(Tree *, int, vlong);
Blk* dupblk(Tree *, Blk*);
Blk* getroot(Tree*, int*);
Blk* getblk(Bptr, int);
@@ -56,9 +59,9 @@
void epochclean(void);
void limbo(Bfree*);
void freeblk(Tree*, Blk*, Bptr);
-int dlappend(Dlist *dl, Bptr);
-int killblk(Tree*, Bptr);
-int blkdealloc(vlong);
+void dlappend(Dlist *dl, Bptr);
+void killblk(Tree*, Bptr);
+void blkdealloc(vlong);
ushort blkfill(Blk*);
uvlong blkhash(Blk*);
uvlong bufhash(void*, usize);
@@ -77,10 +80,10 @@
void closesnap(Tree*);
void reamfs(char*);
void growfs(char*);
-int loadarena(Arena*, Bptr, vlong);
+void loadarena(Arena*, Bptr, vlong);
void loadfs(char*);
void sync(void);
-int loadlog(Arena*, Bptr);
+void loadlog(Arena*, Bptr);
int scandead(Dlist*, int, void(*)(Bptr, void*), void*);
int endfs(void);
int compresslog(Arena*);
@@ -151,7 +154,7 @@
char* packstr(char*, char*, char*);
-int dir2kv(vlong, Xdir*, Kvp*, char*, int);
+void dir2kv(vlong, Xdir*, Kvp*, char*, int);
int dir2statbuf(Xdir*, char*, int);
void dlist2kv(Dlist*, Kvp*, char*, int);
void lbl2kv(char*, vlong, uint, Kvp*, char*, int);
@@ -159,7 +162,7 @@
void retag2kv(vlong, vlong, int, int, Kvp*, char*, int);
void tree2kv(Tree*, Kvp*, char*, int);
-int kv2dir(Kvp*, Xdir*);
+void kv2dir(Kvp*, Xdir*);
void kv2dlist(Kvp*, Dlist*);
void kv2link(Kvp*, vlong*, vlong*);
void kv2qid(Kvp*, Qid*);
--- a/fs.c
+++ b/fs.c
@@ -25,8 +25,7 @@
return -1;
if(!btlookup(t, &k, &kv, rbuf, sizeof(rbuf)))
return -1;
- if(kv2dir(&kv, &d) == -1)
- return -1;
+ kv2dir(&kv, &d);
*qid = d.qid;
*len = d.length;
return 0;
@@ -329,7 +328,7 @@
PACK64(m->k+1, f->qpath);
PACK64(m->k+9, fb);
- b = newdblk(f->mnt->root, Tdat, f->qpath);
+ b = newblk(f->mnt->root, Tdat, f->qpath);
t = nil;
if(lookup(f->mnt, m, &kv, buf, sizeof(buf))){
bp = unpackbp(kv.v, kv.nv);
@@ -688,7 +687,7 @@
return rpc;
}
-static char*
+static void
authread(Fid *f, Fcall *r, void *data, vlong count)
{
AuthInfo *ai;
@@ -696,11 +695,11 @@
User *u;
if((rpc = f->auth) == nil)
- return Etype;
+ error(Etype);
switch(auth_rpc(rpc, "read", nil, 0)){
default:
- return Eauthp;
+ error(Eauthp);
case ARdone:
if((ai = auth_getinfo(rpc)) == nil)
goto Phase;
@@ -709,35 +708,34 @@
auth_freeAI(ai);
if(u == nil){
runlock(&fs->userlk);
- return Enouser;
+ error(Enouser);
}
f->uid = u->id;
runlock(&fs->userlk);
- return nil;
+ return;
case ARok:
if(count < rpc->narg)
- return Eauthd;
+ error(Eauthd);
memmove(data, rpc->arg, rpc->narg);
r->count = rpc->narg;
- return nil;
+ return;
case ARphase:
Phase:
- return Eauthph;
+ error(Eauthph);
}
}
-static char*
+static void
authwrite(Fid *f, Fcall *r, void *data, vlong count)
{
AuthRpc *rpc;
if((rpc = f->auth) == nil)
- return Etype;
+ error(Etype);
if(auth_rpc(rpc, "write", data, count) != ARok)
- return Ebotch;
+ error(Ebotch);
r->type = Rwrite;
r->count = count;
- return nil;
}
@@ -857,7 +855,7 @@
/* uid none gets only other permissions */
if(permissive)
return 0;
- if(f->uid != 0) {
+ if(f->uid != noneid) {
if(f->uid == fuid)
if((m & (fmode>>6)) == m)
return 0;
@@ -868,7 +866,7 @@
if(m & fmode) {
if((fmode & DMDIR) && (m == DMEXEC))
return 0;
- if(!ingroup(f->uid, 9999))
+ if(!ingroup(f->uid, nogroupid))
return 0;
}
return -1;
@@ -877,7 +875,7 @@
static void
fsattach(Fmsg *m)
{
- char *e, *p, *n, dbuf[Kvmax], kvbuf[Kvmax];
+ char *p, *n, dbuf[Kvmax], kvbuf[Kvmax];
Mount *mnt;
Dent *de;
Tree *t;
@@ -924,8 +922,7 @@
putfid(af);
nexterror();
}
- if((e = authread(af, &r, nil, 0)) != nil)
- error(e);
+ authread(af, &r, nil, 0);
if(af->uid != uid)
error(Ebadu);
poperror();
@@ -947,7 +944,7 @@
kv2dir(&kv, &d);
}
if((de = getdent(-1, &d)) == nil)
- error(Efs);
+ broke(Efs);
memset(&f, 0, sizeof(Fid));
f.fid = NOFID;
@@ -1128,7 +1125,8 @@
return;
}
rlock(f->dent);
- n = dir2statbuf(f->dent, buf, sizeof(buf));
+ if((n = dir2statbuf(f->dent, buf, sizeof(buf))) == -1)
+ error(Efs);
runlock(f->dent);
r.type = Rstat;
r.stat = (uchar*)buf;
@@ -1448,10 +1446,7 @@
d.muid = f->uid;
mb[nm].op = Oinsert;
- if(dir2kv(f->qpath, &d, &mb[nm], buf, sizeof(buf)) == -1){
- rerror(m, Efs);
- goto Out;
- }
+ dir2kv(f->qpath, &d, &mb[nm], buf, sizeof(buf));
nm++;
if(m->perm & DMDIR){
@@ -1666,7 +1661,7 @@
putfid(f);
}
-static char*
+static void
readsnap(Fmsg *m, Fid *f, Fcall *r)
{
char pfx[1], *p;
@@ -1676,10 +1671,9 @@
s = f->scan;
if(s != nil && s->offset != 0 && s->offset != m->offset)
- return Edscan;
+ error(Edscan);
if(s == nil || m->offset == 0){
- if((s = mallocz(sizeof(Scan), 1)) == nil)
- return Enomem;
+ s = emalloc(sizeof(Scan), 1);
pfx[0] = Klabel;
btnewscan(s, pfx, 1);
lock(f);
@@ -1691,7 +1685,7 @@
}
if(s->donescan){
r->count = 0;
- return nil;
+ return;
}
p = r->data;
n = m->count;
@@ -1702,7 +1696,7 @@
d.qid.path = UNPACK64(s->kv.v + 1);
if((ns = dir2statbuf(&d, p, n)) == -1){
r->count = 0;
- return nil;
+ return;
}
s->overflow = 0;
p += ns;
@@ -1724,10 +1718,10 @@
}
btexit(s);
r->count = p - r->data;
- return nil;
+ return;
}
-static char*
+static void
readdir(Fmsg *m, Fid *f, Fcall *r)
{
char pfx[Dpfxsz], *p;
@@ -1738,11 +1732,9 @@
s = f->scan;
t = agetp(&f->mnt->root);
if(s != nil && s->offset != 0 && s->offset != m->offset)
- return Edscan;
+ error(Edscan);
if(s == nil || m->offset == 0){
- if((s = mallocz(sizeof(Scan), 1)) == nil)
- return Enomem;
-
+ s = emalloc(sizeof(Scan), 1);
packdkey(pfx, sizeof(pfx), f->qpath, nil);
btnewscan(s, pfx, sizeof(pfx));
lock(f);
@@ -1753,7 +1745,7 @@
}
if(s->donescan){
r->count = 0;
- return nil;
+ return;
}
p = r->data;
n = m->count;
@@ -1760,7 +1752,7 @@
if(s->overflow){
if((ns = kv2statbuf(&s->kv, p, n)) == -1){
r->count = 0;
- return nil;
+ return;
}
s->overflow = 0;
p += ns;
@@ -1779,10 +1771,9 @@
}
btexit(s);
r->count = p - r->data;
- return nil;
}
-static char*
+static void
readfile(Fmsg *m, Fid *f, Fcall *r)
{
vlong n, c, o;
@@ -1793,7 +1784,7 @@
rlock(e);
if(m->offset > e->length){
runlock(e);
- return nil;
+ return;
}
p = r->data;
c = m->count;
@@ -1802,11 +1793,6 @@
c = e->length - m->offset;
while(c != 0){
n = readb(f, p, o, c, e->length);
- if(n == -1){
- fprint(2, "read %K [%Q]@%lld+%lld: %r\n", &e->Key, e->qid, o, c);
- runlock(e);
- return Efs;
- }
r->count += n;
if(n == 0)
break;
@@ -1815,13 +1801,11 @@
c -= n;
}
runlock(e);
- return nil;
}
static void
fsread(Fmsg *m)
{
- char *e;
Fcall r;
Fid *f;
@@ -1831,24 +1815,25 @@
}
r.type = Rread;
r.count = 0;
- if((r.data = malloc(m->count)) == nil){
- rerror(m, Enomem);
+ r.data = nil;
+ if(waserror()){
+ rerror(m, errmsg());
+ free(r.data);
putfid(f);
return;
- }
+ }
+ r.data = emalloc(m->count, 0);
if(f->dent->qid.type & QTAUTH)
- e = authread(f, &r, r.data, m->count);
+ authread(f, &r, r.data, m->count);
else if(f->dent->qid.path == Qdump)
- e = readsnap(m, f, &r);
+ readsnap(m, f, &r);
else if(f->dent->qid.type & QTDIR)
- e = readdir(m, f, &r);
+ readdir(m, f, &r);
else
- e = readfile(m, f, &r);
- if(e != nil)
- rerror(m, e);
- else
- respond(m, &r);
+ readfile(m, f, &r);
+ respond(m, &r);
free(r.data);
+ poperror();
putfid(f);
}
@@ -1859,8 +1844,8 @@
Bptr bp[Max9p/Blksz + 2];
Msg kv[Max9p/Blksz + 2];
vlong n, o, c, w;
- char *p, *e;
int i, j;
+ char *p;
Fcall r;
Tree *t;
Fid *f;
@@ -1886,9 +1871,7 @@
if(f->dent->gone)
error(Ephase);
if(f->dent->qid.type == QTAUTH){
- e = authwrite(f, &r, m->data, m->count);
- if(e != nil)
- error(e);
+ authwrite(f, &r, m->data, m->count);
goto Out;
}
--- a/load.c
+++ b/load.c
@@ -16,7 +16,7 @@
return 0;
}
-int
+void
loadarena(Arena *a, Bptr hdbp, vlong asz)
{
Blk *hd, *tl, *b;
@@ -24,31 +24,37 @@
/* try to load block pointers with consistency check */
bp = hdbp;
- hd = getblk(bp, 0);
+ hd = nil;
+ tl = nil;
+ if(!waserror()){
+ hd = getblk(bp, 0);
+ poperror();
+ }
bp.addr += asz;
- tl = getblk(bp, 0);
+ if(!waserror()){
+ tl = getblk(bp, 0);
+ poperror();
+ }
/* if neither head nor tail is consistent, we're hosed */
b = (hd != nil) ? hd : tl;
if(b == nil)
- return -1;
+ error(Efs);
/* otherwise, we could have crashed mid-pass, just load the blocks */
bp = hdbp;
- if(hd == nil && (hd = getblk(bp, GBnochk)) == nil)
- return -1;
+ if(hd == nil)
+ hd = getblk(bp, GBnochk);
bp.addr += asz;
- if(tl == nil && (tl = getblk(bp, GBnochk)) == nil)
- return -1;
+ if(tl == nil)
+ tl = getblk(bp, GBnochk);
- if(unpackarena(a, b->data, Arenasz) == nil)
- return -1;
+ unpackarena(a, b->data, Arenasz);
if((a->free = avlcreate(rangecmp)) == nil)
- return -1;
+ error(Enomem);
a->hd = hd;
a->tl = tl;
a->used = a->size;
- return 0;
}
void
@@ -64,6 +70,8 @@
sysfatal("malloc: %r");
if((dump->name = strdup("dump")) == nil)
sysfatal("malloc: %r");
+ if(waserror())
+ sysfatal("load fs: %s", errmsg());
dump->ref = 1;
dump->gen = -1;
dump->root = &fs->snap;
@@ -74,20 +82,16 @@
if((fs->fd = open(dev, ORDWR)) == -1)
sysfatal("open %s: %r", dev);
bp = (Bptr){0, -1, -1};
- if((fs->sb0 = getblk(bp, GBnochk)) == nil)
- sysfatal("superblock: %r\n");
+ fs->sb0 = getblk(bp, GBnochk);
bp = (Bptr){512*MiB, -1, -1};
- if((fs->sb1 = getblk(bp, GBnochk)) == nil)
- sysfatal("superblock: %r\n");
- if(unpacksb(fs, fs->sb0->buf, Blksz) == nil)
- sysfatal("superblock: %r");
+ fs->sb1 = getblk(bp, GBnochk);
+ unpacksb(fs, fs->sb0->buf, Blksz);
if((fs->arenas = calloc(fs->narena, sizeof(Arena))) == nil)
sysfatal("malloc: %r");
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
memset(a, 0, sizeof(Arena));
- if((loadarena(a, fs->arenabp[i], fs->arenasz)) == -1)
- sysfatal("loadfs: %r");
+ loadarena(a, fs->arenabp[i], fs->arenasz);
a->reserve = a->size / 1024;
if(a->reserve < 32*MiB)
a->reserve = 32*MiB;
@@ -105,12 +109,9 @@
a->logbuf[1] = cachepluck();
a->logbuf[0]->bp = (Bptr){-1, -1, -1};
a->logbuf[1]->bp = (Bptr){-1, -1, -1};
- if(loadlog(a, a->loghd) == -1)
- sysfatal("load log %B: %r", a->loghd);
+ loadlog(a, a->loghd);
}
- if(waserror())
- sysfatal("load fs: %s\n", errmsg());
if((t = opensnap("adm", nil)) == nil)
sysfatal("load users: no adm label");
loadusers(2, t);
--- a/main.c
+++ b/main.c
@@ -17,9 +17,11 @@
int nproc;
int permissive;
char *reamuser;
-char *srvname = "gefs";
char *dev;
-vlong cachesz = 512*MiB;
+vlong cachesz = 512*MiB;
+char *srvname = "gefs";
+int noneid = 0;
+int nogroupid = 9999;
Blk *blkbuf;
void **errctx;
@@ -65,7 +67,6 @@
errorv(fmt, ap);
}
-
_Noreturn void
nexterror(void)
{
@@ -74,6 +75,16 @@
c = *errctx;
assert(c->nerrlab > 0 && c->nerrlab < Estacksz);
longjmp(c->errlab[--c->nerrlab], -1);
+}
+
+void*
+emalloc(usize sz, int zero)
+{
+ void *p;
+
+ if((p = mallocz(sz, zero)) == nil)
+ error(Enomem);
+ return p;
}
static void
--- a/pack.c
+++ b/pack.c
@@ -16,7 +16,7 @@
error(Elength);
n = UNPACK16(p);
if(e - p < n + 3 || p[n+2] != 0)
- error(Efs);
+ broke(Efs);
*s = p+2;
return p+3+n;
}
@@ -36,7 +36,7 @@
return p;
}
-int
+void
dir2kv(vlong up, Xdir *d, Kvp *kv, char *buf, int nbuf)
{
char *ek, *ev, *eb;
@@ -48,7 +48,6 @@
ev = packdval(ek, eb - ek, d);
kv->v = ek;
kv->nv = ev - ek;
- return 0;
}
char*
@@ -112,7 +111,7 @@
return p;
}
-int
+void
kv2dir(Kvp *kv, Xdir *d)
{
char *k, *ek, *v, *ev;
@@ -137,28 +136,26 @@
d->muid = UNPACK32(v); v += 4;
assert(v <= ev);
if(k != ek)
- error(Efs);
+ broke(Efs);
if(v != ev)
- error(Efs);
- return 0;
+ broke(Efs);
}
int
dir2statbuf(Xdir *d, char *buf, int nbuf)
{
- int sz, nn, nu, ng, nm, ret;
+ int sz, nn, nu, ng, nm;
vlong atime, mtime;
User *u, *g, *m;
char *p;
- ret = -1;
rlock(&fs->userlk);
if((u = uid2user(d->uid)) == nil)
- goto Out;
+ u = uid2user(noneid);
if((g = uid2user(d->gid)) == nil)
- goto Out;
+ u = uid2user(nogroupid);
if((m = uid2user(d->muid)) == nil)
- goto Out;
+ m = uid2user(noneid);
p = buf;
nn = strlen(d->name);
@@ -168,8 +165,10 @@
atime = (d->atime+Nsec/2)/Nsec;
mtime = (d->mtime+Nsec/2)/Nsec;
sz = STATFIXLEN + nn + nu + ng + nm;
- if(sz > nbuf)
- goto Out;
+ if(sz > nbuf){
+ runlock(&fs->userlk);
+ return -1;
+ }
PBIT16(p, sz-2); p += 2;
PBIT16(p, -1 /*type*/); p += 2;
@@ -191,10 +190,8 @@
PBIT16(p, nm); p += 2;
memcpy(p, m->name, nm); p += nm;
assert(p - buf == sz);
- ret = sz;
-Out:
runlock(&fs->userlk);
- return ret;
+ return sz;
}
int
@@ -467,10 +464,8 @@
int i;
assert(sz == Blksz);
- if(memcmp(p, "gefs0008", 8) != 0){
- werrstr("wrong block header %.8s\n", p);
- return nil;
- }
+ if(memcmp(p, "gefs0008", 8) != 0)
+ error("%s %.8s", Efsvers, p);
p += 8;
fi->blksz = UNPACK32(p); p += 4;
fi->bufspc = UNPACK32(p); p += 4;
--- a/ream.c
+++ b/ream.c
@@ -50,20 +50,16 @@
fillxdir(&d, Qadmuser, "users", QTFILE, 0664);
d.length = nu;
- if(dir2kv(Qadmroot, &d, &kv, vbuf, sizeof(vbuf)) == -1)
- sysfatal("ream: pack users: %r");
+ dir2kv(Qadmroot, &d, &kv, vbuf, sizeof(vbuf));
setval(r, &kv);
fillxdir(&d, Qadmroot, "", QTDIR, DMDIR|0775);
- if(dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf)) == -1)
- sysfatal("ream: pack root: %r");
+ dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf));
setval(r, &kv);
- if((p = packsuper(kbuf, sizeof(kbuf), 0)) == nil)
- sysfatal("ream: pack super");
+ p = packsuper(kbuf, sizeof(kbuf), 0);
kv.k = kbuf;
kv.nk = p - kbuf;
- if((p = packdkey(vbuf, sizeof(vbuf), -1, "")) == nil)
- sysfatal("ream: pack super");
+ p = packdkey(vbuf, sizeof(vbuf), -1, "");
kv.v = vbuf;
kv.nv = p - vbuf;
setval(r, &kv);
@@ -78,16 +74,13 @@
/* nb: values must be inserted in key order */
fillxdir(&d, Qmainroot, "", QTDIR, DMDIR|0775);
- if(dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf)) == -1)
- sysfatal("ream: pack root: %r");
+ dir2kv(-1, &d, &kv, vbuf, sizeof(vbuf));
setval(r, &kv);
- if((p = packsuper(kbuf, sizeof(kbuf), 0)) == nil)
- sysfatal("ream: pack super");
+ p = packsuper(kbuf, sizeof(kbuf), 0);
kv.k = kbuf;
kv.nk = p - kbuf;
- if((p = packdkey(vbuf, sizeof(vbuf), -1, "")) == nil)
- sysfatal("ream: pack super");
+ p = packdkey(vbuf, sizeof(vbuf), -1, "");
kv.v = vbuf;
kv.nv = p - vbuf;
setval(r, &kv);
@@ -271,14 +264,10 @@
if(sz < 512*MiB+Blksz)
sysfatal("ream: disk too small");
- if((mnt = mallocz(sizeof(Mount), 1)) == nil)
- sysfatal("ream: alloc mount: %r");
- if((mnt->root = mallocz(sizeof(Tree), 1)) == nil)
- sysfatal("ream: alloc tree: %r");
- if((adm = mallocz(sizeof(Mount), 1)) == nil)
- sysfatal("ream: alloc mount: %r");
- if((adm->root = mallocz(sizeof(Tree), 1)) == nil)
- sysfatal("ream: alloc tree: %r");
+ mnt = emalloc(sizeof(Mount), 1);
+ mnt->root = mallocz(sizeof(Tree), 1);
+ adm = mallocz(sizeof(Mount), 1);
+ adm->root = mallocz(sizeof(Tree), 1);
sz = sz - sz%Blksz - 2*Blksz;
@@ -287,8 +276,7 @@
fs->narena = 8;
if(fs->narena >= 128)
fs->narena = 128;
- if((fs->arenas = calloc(fs->narena, sizeof(Arena))) == nil)
- sysfatal("malloc: %r");
+ fs->arenas = emalloc(fs->narena*sizeof(Arena), 1);
off = Blksz;
@@ -301,7 +289,7 @@
sb0->bp = (Bptr){0, -1, -1};
sb1->bp = (Bptr){512*MiB, -1, -1};
- fs->arenabp = malloc(fs->narena * sizeof(Bptr));
+ fs->arenabp = emalloc(fs->narena * sizeof(Bptr), 1);
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
print("\tarena %d: %lld blocks at %llx\n", i, asz/Blksz, off);
@@ -312,13 +300,11 @@
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
- if((loadarena(a, a->hd->bp, asz)) == -1)
- sysfatal("ream: loadarena: %r");
- if(loadlog(a, a->loghd) == -1)
- sysfatal("load log: %r");
+ loadarena(a, a->hd->bp, asz);
+ loadlog(a, a->loghd);
}
- if((mb = newblk(mnt->root, Tleaf)) == nil)
+ if((mb = newblk(mnt->root, Tleaf, 0)) == nil)
sysfatal("ream: allocate root: %r");
holdblk(mb);
initroot(mb);
@@ -328,9 +314,9 @@
mnt->root->ht = 1;
mnt->root->bp = mb->bp;
- if((ab = newblk(adm->root, Tleaf)) == nil)
+ if((ab = newblk(adm->root, Tleaf, 0)) == nil)
sysfatal("ream: allocate root: %r");
- if((ub = newblk(adm->root, Tdat)) == nil)
+ if((ub = newblk(adm->root, Tdat, 0)) == nil)
sysfatal("ream: allocate root: %r");
holdblk(ab);
holdblk(ub);
@@ -356,7 +342,7 @@
* a single snap block that the tree will insert
* into, and take a snapshot as the initial state.
*/
- if((tb = newblk(mnt->root, Tleaf)) == nil)
+ if((tb = newblk(mnt->root, Tleaf, 0)) == nil)
sysfatal("ream: allocate snaps: %r");
holdblk(tb);
initsnap(tb, mb, ab);
@@ -444,8 +430,7 @@
sysfatal("malloc: %r");
for(i = 0; i < fs->narena; i++){
a = &fs->arenas[i];
- if((loadarena(a, fs->arenabp[i], fs->arenasz)) == -1)
- sysfatal("growfs: %r");
+ loadarena(a, fs->arenabp[i], fs->arenasz);
}
narena = sz/fs->arenasz;
off = fs->arenasz * fs->narena;
@@ -452,15 +437,14 @@
if(narena <= fs->narena)
sysfatal("disk too small for more arenas");
if((fs->arenas = realloc(fs->arenas, narena*sizeof(Arena))) == nil)
- sysfatal("malloc: %r");
+ error(Enomem);
if((fs->arenabp = realloc(fs->arenas, narena*sizeof(Bptr))) == nil)
- sysfatal("malloc: %r");
+ error(Enomem);
for(i = fs->narena; i < narena; i++){
a = &fs->arenas[i];
print("\tadding %d: %lld blocks at %llx\n", i, fs->arenasz/Blksz, off);
initarena(&fs->arenas[i], off, fs->arenasz);
- if((loadarena(a, fs->arenabp[i], fs->arenasz)) == -1)
- sysfatal("growfs: %r");
+ loadarena(a, fs->arenabp[i], fs->arenasz);
fs->arenabp[i] = a->hd->bp;
off += fs->arenasz;
}
--- a/snap.c
+++ b/snap.c
@@ -80,8 +80,7 @@
if((dl = dlcacheget(gen, bgen)) != nil)
return dl;
- if((dl = mallocz(sizeof(Dlist), 1)) == nil)
- error(Enomem);
+ dl = emalloc(sizeof(Dlist), 1);
if(waserror()){
free(dl);
nexterror();
@@ -124,8 +123,9 @@
{
Dlist *dt;
+ if(dl == &fs->snapdl)
+ return;
dlcachedel(dl, 0);
-
while(fs->dltail != nil && fs->dlcount >= fs->dlcmax){
dt = fs->dltail;
dlsync(dt);
@@ -344,8 +344,7 @@
nexterror();
}
if(mutable){
- if((n = mallocz(sizeof(Tree), 1)) == nil)
- error(Enomem);
+ n = emalloc(sizeof(Tree), 1);
n->memref = 1;
n->dirty = 0;
n->nlbl = 1;
@@ -409,8 +408,7 @@
/* create the new one */
- if((t = mallocz(sizeof(Tree), 1)) == nil)
- error(Enomem);
+ t = emalloc(sizeof(Tree), 1);
if(waserror()){
free(t);
nexterror();
@@ -483,8 +481,7 @@
if(mut != nil)
*mut = !!(flg&Lmut);
- if((t = mallocz(sizeof(Tree), 1)) == nil)
- error(Enomem);
+ t = mallocz(sizeof(Tree), 1);
if(waserror()){
free(t);
nexterror();
@@ -512,8 +509,7 @@
if(t == nil || adec(&t->memref) != 0)
return;
- if((f = malloc(sizeof(Bfree))) == nil)
- abort();
+ f = malloc(sizeof(Bfree));
f->op = DFtree;
f->t = t;
limbo(f);
@@ -548,7 +544,7 @@
* t must be an active snapshot with
* no successors.
*/
-int
+void
killblk(Tree *t, Bptr bp)
{
Dlist *dl;
@@ -555,18 +551,23 @@
Blk *b;
char *p;
- /* leak it and let the full collection clean it up */
+ /*
+ * When we have a forked snap, blocks allocated before the fork
+ * are the responsibility of the other chain; in this chain, we
+ * leak it and let the last reference in the other chain clean up
+ */
if(bp.gen <= t->base)
- return 0;
+ return;
if(t == &fs->snap)
dl = &fs->snapdl;
- else if((dl = getdl(t->gen, bp.gen)) == nil)
- return -1;
+ else
+ dl = getdl(t->gen, bp.gen);
+ if(waserror()){
+ putdl(dl);
+ nexterror();
+ }
if(dl->ins == nil || Logspc - dl->ins->logsz < Logslop){
- if((b = newblk(&fs->snap, Tdlist)) == nil){
- putdl(dl);
- return -1;
- }
+ b = newblk(&fs->snap, Tdlist, 0);
if(dl->ins != nil)
enqueue(dl->ins);
if(dl->tl.addr == -1)
@@ -580,7 +581,6 @@
dl->ins->logsz += 8;
setflag(dl->ins, Bdirty);
PACK64(p, bp.addr);
- if(t != &fs->snap)
- putdl(dl);
- return 0;
+ poperror();
+ putdl(dl);
}
--- a/tree.c
+++ b/tree.c
@@ -482,7 +482,7 @@
*/
full = 0;
spc = Leafspc - blkfill(b);
- n = newblk(t, b->type);
+ n = newblk(t, b->type, 0);
assert(i >= 0 && j >= 0);
while(i < b->nval){
ok = 1;
@@ -573,7 +573,7 @@
Msg m, u;
b = p->b;
- n = newblk(t, b->type);
+ n = newblk(t, b->type, 0);
for(i = 0; i < b->nval; i++){
if(pp != nil && i == p->midx){
copyup(n, pp, nil);
@@ -656,8 +656,8 @@
efreeblk(t, r);
nexterror();
}
- l = newblk(t, b->type);
- r = newblk(t, b->type);
+ l = newblk(t, b->type, 0);
+ r = newblk(t, b->type, 0);
d = l;
i = 0;
@@ -754,8 +754,8 @@
efreeblk(t, r);
nexterror();
}
- l = newblk(t, b->type);
- r = newblk(t, b->type);
+ l = newblk(t, b->type, 0);
+ r = newblk(t, b->type, 0);
d = l;
copied = 0;
halfsz = (2*b->nval + b->valsz)/2;
@@ -804,7 +804,7 @@
Msg m;
int i;
- d = newblk(t, a->type);
+ d = newblk(t, a->type, 0);
for(i = 0; i < a->nval; i++){
getval(a, i, &m);
setval(d, &m);
@@ -888,8 +888,8 @@
efreeblk(t, r);
nexterror();
}
- l = newblk(t, a->type);
- r = newblk(t, a->type);
+ l = newblk(t, a->type, 0);
+ r = newblk(t, a->type, 0);
d = l;
cp = 0;
sp = -1;
@@ -1073,7 +1073,7 @@
}
if(pp->nl != nil && pp->nr != nil){
rp = &path[0];
- rp->nl = newblk(t, Tpivot);
+ rp->nl = newblk(t, Tpivot, 0);
rp->npull = pp->npull;
rp->pullsz = pp->pullsz;
copyup(rp->nl, pp, nil);
@@ -1222,7 +1222,6 @@
freepath(t, path, npath);
nexterror();
}
-int eb;
Again:
b = getroot(t, &height);
--- a/user.c
+++ b/user.c
@@ -125,15 +125,18 @@
err = Esyntax;
goto Error;
}
- users[i].id = atol(f);
+ u = &users[i];
+ u->id = atol(f);
if((f = getfield(&p, ':')) == nil){
fprint(fd, "/adm/users:%d: missing ':' after name\n", lnum);
err = Esyntax;
goto Error;
}
- snprint(users[i].name, sizeof(users[i].name), "%s", f);
- users[i].memb = nil;
- users[i].nmemb = 0;
+ snprint(u->name, sizeof(u->name), "%s", f);
+ u->memb = nil;
+ u->nmemb = 0;
+ if(strcmp(u->name, "none") == 0)
+ noneid = u->id;
i++;
}
nusers = i;
@@ -190,6 +193,8 @@
}
grp = g;
grp[ngrp++] = u->id;
+ if(strcmp(u->name, "nogroup") == 0)
+ nogroupid = u->id;
}
users[i].memb = grp;
users[i].nmemb = ngrp;