commit b30db499a59ec215edb9a96f4b0d7fd517dab34b
parent 9be48e61285e87fff2638f5b2acee3e15a00046c
Author: sin <sin@2f30.org>
Date: Fri, 3 May 2019 15:18:53 +0100
Add error reporting to bstorage.c
Diffstat:
M | bstorage.c | | | 107 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
1 file changed, 86 insertions(+), 21 deletions(-)
diff --git a/bstorage.c b/bstorage.c
@@ -219,22 +219,27 @@ loadbd(struct sctx *sctx)
struct bd *bd;
bd = calloc(1, sizeof(*bd));
- if (bd == NULL)
+ if (bd == NULL) {
+ bseterr("out of memory");
return -1;
+ }
if (unpackbd(sctx->fd, bd) < 0) {
free(bd);
+ bseterr("failed to unpack block descriptor");
return -1;
}
if (bd->type != BDTYPE) {
free(bd);
+ bseterr("invalid block descriptor type: %d", bd->type);
return -1;
}
/* Move to the next block descriptor */
if (lseek(sctx->fd, bd->size, SEEK_CUR) < 0) {
free(bd);
+ bseterr("failed to seek on storage descriptor");
return -1;
}
@@ -294,16 +299,21 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar)
struct bhdr *bhdr;
int fd;
- if (sodium_init() < 0)
+ if (sodium_init() < 0) {
+ bseterr("crypto library failed to initialize");
return -1;
+ }
fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode);
- if (fd < 0)
+ if (fd < 0) {
+ bseterr("failed to open");
return -1;
+ }
bctx->sctx = calloc(1, sizeof(struct sctx));
if (bctx->sctx == NULL) {
close(fd);
+ bseterr("out of memory");
return -1;
}
@@ -322,6 +332,7 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar)
} else {
free(sctx);
close(fd);
+ bseterr("invalid compression type: %s", bpar->calgo);
return -1;
}
@@ -333,6 +344,7 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar)
} else {
free(sctx);
close(fd);
+ bseterr("invalid encryption type: %s", bpar->ealgo);
return -1;
}
@@ -343,6 +355,7 @@ bscreat(struct bctx *bctx, char *path, int mode, struct bparam *bpar)
if (packbhdr(fd, bhdr) < 0) {
free(sctx);
close(fd);
+ bseterr("failed to write block header entry");
return -1;
}
return 0;
@@ -364,19 +377,25 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar)
flags = O_RDWR;
break;
default:
+ bseterr("invalid params");
return -1;
}
- if (sodium_init() < 0)
+ if (sodium_init() < 0) {
+ bseterr("crypto library failed to initialize");
return -1;
+ }
fd = open(path, flags, mode);
- if (fd < 0)
+ if (fd < 0) {
+ bseterr("failed to open");
return -1;
+ }
bctx->sctx = calloc(1, sizeof(struct sctx));
if (bctx->sctx == NULL) {
close(fd);
+ bseterr("out of memory");
return -1;
}
@@ -389,6 +408,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar)
if (unpackbhdr(fd, bhdr) < 0) {
free(sctx);
close(fd);
+ bseterr("failed to read block header entry");
return -1;
}
@@ -396,6 +416,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar)
if (memcmp(bhdr->magic, BHDRMAGIC, NBHDRMAGIC) != 0) {
free(sctx);
close(fd);
+ bseterr("unknown block header magic");
return -1;
}
@@ -403,6 +424,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar)
if (((bhdr->flags >> VMAJSHIFT) & VMAJMASK) != VMAJ) {
free(sctx);
close(fd);
+ bseterr("block header version mismatch");
return -1;
}
@@ -418,6 +440,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar)
default:
free(sctx);
close(fd);
+ bseterr("invalid compression type: %d", algo);
return -1;
}
@@ -433,6 +456,7 @@ bsopen(struct bctx *bctx, char *path, int flags, int mode, struct bparam *bpar)
default:
free(sctx);
close(fd);
+ bseterr("invalid encryption type: %d", algo);
return -1;
}
@@ -460,8 +484,10 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
struct bd key, *bd;
off_t offs;
- if (bhash(buf, n, key.md) < 0)
+ if (bhash(buf, n, key.md) < 0) {
+ bseterr("failed to hash block");
return -1;
+ }
/*
* If the block is already present in the cache
@@ -474,12 +500,15 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
off_t bdoffs;
bdoffs = bd->offset - BDSIZE;
- if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0)
+ if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0) {
+ bseterr("failed to seek on storage descriptor");
return -1;
+ }
bd->refcnt++;
if (packbd(sctx->fd, bd) < 0) {
bd->refcnt--;
+ bseterr("failed to write block descriptor");
return -1;
}
@@ -489,13 +518,17 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
/* New blocks are always appended to the storage file */
offs = lseek(sctx->fd, 0, SEEK_END);
- if (offs < 0)
+ if (offs < 0) {
+ bseterr("failed to seek on storage descriptor");
return -1;
+ }
/* Allocate a new block descriptor */
bd = calloc(1, sizeof(*bd));
- if (bd == NULL)
+ if (bd == NULL) {
+ bseterr("out of memory");
return -1;
+ }
bd->type = BDTYPE;
bd->offset = offs + BDSIZE;
bd->size = n;
@@ -505,6 +538,7 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
/* Write block descriptor to storage file */
if (packbd(sctx->fd, bd) < 0) {
free(bd);
+ bseterr("failed to write block descriptor");
return -1;
}
@@ -513,6 +547,7 @@ bsput(struct bctx *bctx, void *buf, size_t n, unsigned char *md)
/* Shouldn't fail but if it does rewind storage file state */
ftruncate(sctx->fd, offs);
free(bd);
+ bseterr("failed to write block");
return -1;
}
@@ -541,16 +576,24 @@ bsget(struct bctx *bctx, unsigned char *md, void *buf, size_t *n)
/* Lookup block in the cache */
memcpy(key.md, md, MDSIZE);
bd = RB_FIND(bdcache, &sctx->bdcache, &key);
- if (bd == NULL)
+ if (bd == NULL) {
+ bseterr("unknown block");
return -1;
+ }
- if (*n < bd->size)
+ if (*n < bd->size) {
+ bseterr("buffer too small");
return -1;
+ }
- if (lseek(sctx->fd, bd->offset, SEEK_SET) < 0)
+ if (lseek(sctx->fd, bd->offset, SEEK_SET) < 0) {
+ bseterr("failed to seek on storage descriptor");
return -1;
- if (xread(sctx->fd, buf, bd->size) != bd->size)
+ }
+ if (xread(sctx->fd, buf, bd->size) != bd->size) {
+ bseterr("failed to read block");
return -1;
+ }
*n = bd->size;
return 0;
}
@@ -568,16 +611,21 @@ bsrm(struct bctx *bctx, unsigned char *md)
/* Lookup block in the cache */
memcpy(key.md, md, MDSIZE);
bd = RB_FIND(bdcache, &sctx->bdcache, &key);
- if (bd == NULL)
+ if (bd == NULL) {
+ bseterr("unknown block");
return -1;
+ }
bdoffs = bd->offset - BDSIZE;
- if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0)
+ if (lseek(sctx->fd, bdoffs, SEEK_SET) < 0) {
+ bseterr("failed to seek on storage descriptor");
return -1;
+ }
bd->refcnt--;
if (packbd(sctx->fd, bd) < 0) {
bd->refcnt++;
+ bseterr("failed to write block descriptor");
return -1;
}
@@ -593,6 +641,7 @@ bsrm(struct bctx *bctx, unsigned char *md)
lseek(sctx->fd, bdoffs, SEEK_SET);
bd->refcnt++;
packbd(sctx->fd, bd);
+ bseterr("operation not supported");
return -1;
}
@@ -644,28 +693,38 @@ bscheck(struct bctx *bctx, unsigned char *md)
/* Lookup block in the cache */
memcpy(key.md, md, MDSIZE);
bd = RB_FIND(bdcache, &sctx->bdcache, &key);
- if (bd == NULL)
+ if (bd == NULL) {
+ bseterr("unknown block");
return -1;
+ }
- if (lseek(sctx->fd, bd->offset, SEEK_SET) < 0)
+ if (lseek(sctx->fd, bd->offset, SEEK_SET) < 0) {
+ bseterr("failed to seek on storage descriptor");
return -1;
+ }
buf = malloc(bd->size);
- if (buf == NULL)
+ if (buf == NULL) {
+ bseterr("out of memory");
return -1;
+ }
if (xread(sctx->fd, buf, bd->size) != bd->size) {
free(buf);
+ bseterr("failed to read block");
return -1;
}
if (bhash(buf, bd->size, key.md) < 0) {
free(buf);
+ bseterr("failed to hash block");
return -1;
}
- if (memcmp(key.md, md, MDSIZE) != 0)
+ if (memcmp(key.md, md, MDSIZE) != 0) {
+ bseterr("block mismatch");
return -1;
+ }
return 0;
}
@@ -680,11 +739,15 @@ bssync(struct bctx *bctx)
if (sctx->rdonly)
return 0;
- if (lseek(sctx->fd, 0, SEEK_SET) < 0)
+ if (lseek(sctx->fd, 0, SEEK_SET) < 0) {
+ bseterr("failed to seek on storage descriptor");
return -1;
+ }
bhdr = &sctx->bhdr;
- if (packbhdr(sctx->fd, bhdr) < 0)
+ if (packbhdr(sctx->fd, bhdr) < 0) {
+ bseterr("failed to write block header");
return -1;
+ }
fsync(sctx->fd);
return 0;
}
@@ -714,6 +777,8 @@ bsclose(struct bctx *bctx)
r = close(sctx->fd);
free(sctx);
+ if (r < 0)
+ bseterr("failed to close storage descriptor");
return r;
}