Commit 9d149a70 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

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: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
Reviewed-on: https://review.gerrithub.io/416230


Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Tested-by: default avatarSPDK Automated Test System <sys_sgsw@intel.com>
parent 8f26b74e
Loading
Loading
Loading
Loading
+14 −26
Original line number Diff line number Diff line
@@ -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,16 +2719,12 @@ _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);
	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--;
		}
			segment >>= 1U;
		}
	}

	spdk_dma_free(ctx->mask);
@@ -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);