From 9d149a706b173934c229239321cc39ad6309ca77 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Wed, 20 Jun 2018 10:38:26 -0700 Subject: [PATCH] blob: fix load of non-multiple-of-8 masks Previously, the blobstore load code was iterating over the masks (blob IDs, clusters) byte by byte, then bit by bit in a nested loop, but it was rounding incorrectly and skipping any bits set in the last byte if the total size was not a multiple of 8. Replace the nested loops with a single loop iterating over bits to simplify the code and avoid the bug. Change-Id: Ib365421bf3ba1002d2e5634b34c2bcf9ef7d1267 Signed-off-by: Daniel Verkamp Reviewed-on: https://review.gerrithub.io/416230 Reviewed-by: Jim Harris Reviewed-by: Ben Walker Tested-by: SPDK Automated Test System --- lib/blob/blobstore.c | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 003d1ed88..f650aa0a5 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -2665,7 +2665,7 @@ static void _spdk_bs_load_used_blobids_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) { struct spdk_bs_load_ctx *ctx = cb_arg; - uint32_t i, j; + uint32_t i; int rc; /* The type must be correct */ @@ -2686,13 +2686,9 @@ _spdk_bs_load_used_blobids_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrn return; } - for (i = 0; i < ctx->mask->length / 8; i++) { - uint8_t segment = ctx->mask->mask[i]; - for (j = 0; segment; j++) { - if (segment & 1U) { - spdk_bit_array_set(ctx->bs->used_blobids, (i * 8) + j); - } - segment >>= 1U; + for (i = 0; i < ctx->mask->length; i++) { + if (ctx->mask->mask[i / 8] & (1U << (i % 8))) { + spdk_bit_array_set(ctx->bs->used_blobids, i); } } @@ -2704,7 +2700,7 @@ _spdk_bs_load_used_clusters_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserr { struct spdk_bs_load_ctx *ctx = cb_arg; uint64_t lba, lba_count, mask_size; - uint32_t i, j; + uint32_t i; int rc; /* The type must be correct */ @@ -2723,15 +2719,11 @@ _spdk_bs_load_used_clusters_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserr } ctx->bs->num_free_clusters = ctx->bs->total_clusters; - for (i = 0; i < ctx->mask->length / 8; i++) { - uint8_t segment = ctx->mask->mask[i]; - for (j = 0; segment && (j < 8); j++) { - if (segment & 1U) { - spdk_bit_array_set(ctx->bs->used_clusters, (i * 8) + j); - assert(ctx->bs->num_free_clusters > 0); - ctx->bs->num_free_clusters--; - } - segment >>= 1U; + for (i = 0; i < ctx->mask->length; i++) { + if (ctx->mask->mask[i / 8] & (1U << (i % 8))) { + spdk_bit_array_set(ctx->bs->used_clusters, i); + assert(ctx->bs->num_free_clusters > 0); + ctx->bs->num_free_clusters--; } } @@ -2755,7 +2747,7 @@ _spdk_bs_load_used_pages_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) { struct spdk_bs_load_ctx *ctx = cb_arg; uint64_t lba, lba_count, mask_size; - uint32_t i, j; + uint32_t i; int rc; /* The type must be correct */ @@ -2773,13 +2765,9 @@ _spdk_bs_load_used_pages_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) return; } - for (i = 0; i < ctx->mask->length / 8; i++) { - uint8_t segment = ctx->mask->mask[i]; - for (j = 0; segment && (j < 8); j++) { - if (segment & 1U) { - spdk_bit_array_set(ctx->bs->used_md_pages, (i * 8) + j); - } - segment >>= 1U; + for (i = 0; i < ctx->mask->length; i++) { + if (ctx->mask->mask[i / 8] & (1U << (i % 8))) { + spdk_bit_array_set(ctx->bs->used_md_pages, i); } } spdk_dma_free(ctx->mask);