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 <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/416230
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Daniel Verkamp 2018-06-20 10:38:26 -07:00
parent 8f26b74e02
commit 9d149a706b

View File

@ -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);