Skip to content
Permalink
Browse files

kv: fix too small read buffer size, and add checks to catch this happ…

…ening
  • Loading branch information...
jacobgorm committed Apr 11, 2019
1 parent d7a976d commit 6d2a3c208db1654e95c4d020cf2f6c6038a821ec
Showing with 19 additions and 7 deletions.
  1. +4 −2 block-swap.c
  2. +10 −2 block-swap/dubtree.c
  3. +2 −1 block-swap/dubtree.h
  4. +3 −2 kv.c
@@ -1242,7 +1242,8 @@ static int __swap_dubtree_read(BDRVSwapState *s, SwapAIOCB *acb)
}
acb->sizes = sizes;

decomp = malloc((DUBTREE_BLOCK_SIZE + CRYPTO_IV_SIZE) * (end - start));
size_t decomp_size = (DUBTREE_BLOCK_SIZE + CRYPTO_IV_SIZE) * (end - start);
decomp = malloc(decomp_size);

if (!decomp) {
errx(1, "OOM error %s line %d", __FUNCTION__, __LINE__);
@@ -1258,7 +1259,8 @@ static int __swap_dubtree_read(BDRVSwapState *s, SwapAIOCB *acb)

int retries = 0;
do {
r = dubtree_find(&s->t, start, end - start, decomp,
r = dubtree_find(&s->t, start, end - start,
decomp, decomp_size,
map, sizes,
dubtree_read_complete_cb, acb, s->find_context);
} while (r == -EAGAIN && ++retries < 10);
@@ -763,7 +763,8 @@ void dubtree_end_find(DubTree *t, void *ctx)
}

int dubtree_find(DubTree *t, uint64_t start, int num_keys,
uint8_t *buffer, uint8_t *map, uint32_t *sizes,
uint8_t *buffer, size_t buffer_size,
uint8_t *map, uint32_t *sizes,
read_callback cb, void *opaque, void *ctx)
{
int i, r;
@@ -913,19 +914,26 @@ int dubtree_find(DubTree *t, uint64_t start, int num_keys,
hashtable_init(&c.ht, NULL, NULL);

int dst;
uint32_t read_total = 0;
for (i = dst = 0; i < num_keys; ++i) {
int size = sources[i].size;
if (size) {
read_chunk(t, &c, sources[i].chunk_id, dst, sources[i].offset,
size);
}
sizes[i] = size;
read_total += size;
memcpy(hashes + CRYPTO_TAG_SIZE * i, sources[i].hash.bytes,
CRYPTO_TAG_SIZE);
dst += size;
}

r = flush_reads(t, &c, NULL, 0, cs);
if (read_total <= buffer_size) {
r = flush_reads(t, &c, NULL, 0, cs);
} else {
assert(0); // XXX we lack a proper way to propagate back buffer too small errs
r = -1;
}
if (r < 0) {
succeeded = 0;
}
@@ -84,7 +84,8 @@ void *dubtree_prepare_find(DubTree *t);
void dubtree_end_find(DubTree *t, void *ctx);

int dubtree_find(DubTree *t, uint64_t start, int num_keys,
uint8_t *out, uint8_t *map, uint32_t *sizes,
uint8_t *out, size_t buffer_size,
uint8_t *map, uint32_t *sizes,
read_callback cb, void *opaque, void *ctx);

int dubtree_init(DubTree *t, const uint8_t *key,
5 kv.c
@@ -86,7 +86,7 @@ int kv_global_init(void) {
return 0;
}

#define BUFFER_MAX (8<<20)
#define BUFFER_MAX (32<<20)

int kv_init(struct kv *kv, const char *kvinfo, int delete_on_close) {
memset(kv, 0, sizeof(*kv));
@@ -266,7 +266,8 @@ int kv_find(struct kv *kv, uint8_t **rptr, size_t *rsize, uint64_t key) {
kv->base = base;
kv->last_found = ~0ULL;
do {
r = dubtree_find(kv->t, base, range, kv->buffer, NULL, kv->sizes,
r = dubtree_find(kv->t, base, range, kv->buffer, BUFFER_MAX,
NULL, kv->sizes,
io_done, kv, kv->find_context);
} while (r == -EAGAIN);
wait(kv);

0 comments on commit 6d2a3c2

Please sign in to comment.
You can’t perform that action at this time.