From eb8ee073c57664a3649466dd2bab5ff416d05f37 Mon Sep 17 00:00:00 2001 From: Jim Harris Date: Thu, 26 Jul 2018 13:26:03 -0700 Subject: [PATCH] blobstore: recalculate total clusters after reading super block Blobstore uses 1MB cluster size by default, but logical volumes override it to 4MB by default. When an existing lvolstore is loaded, all cluster calculations were being done based on the 1MB size - not the 4MB cluster size read from the superblock. That would result in asserts (due to mismatched used cluster mask size) and all kinds of other possible weirdness with subsequent operations. Fixes: 2c91e91907e2 ("blobstore: Save the original size of the disk.") Signed-off-by: Jim Harris Change-Id: I5d57c2b64aba791903e69560b9fe5684a72669df Reviewed-on: https://review.gerrithub.io/420582 Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Ben Walker Reviewed-by: Seth Howell Reviewed-by: Changpeng Liu Reviewed-by: Shuhei Matsumoto Tested-by: SPDK CI Jenkins --- lib/blob/blobstore.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/blob/blobstore.c b/lib/blob/blobstore.c index 35c7ab4c59..8356ee11d8 100644 --- a/lib/blob/blobstore.c +++ b/lib/blob/blobstore.c @@ -3053,6 +3053,7 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) { struct spdk_bs_load_ctx *ctx = cb_arg; uint32_t crc; + int rc; static const char zeros[SPDK_BLOBSTORE_TYPE_LENGTH]; if (ctx->super->version > SPDK_BS_VERSION || @@ -3085,22 +3086,27 @@ _spdk_bs_load_super_cpl(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno) return; } - if (ctx->super->size == 0) { - /* Update number of blocks for blobstore */ - ctx->bs->total_clusters = ctx->bs->dev->blockcnt * ctx->bs->dev->blocklen / ctx->bs->cluster_sz; - } else if (ctx->super->size > ctx->bs->dev->blockcnt * ctx->bs->dev->blocklen) { + if (ctx->super->size > ctx->bs->dev->blockcnt * ctx->bs->dev->blocklen) { SPDK_NOTICELOG("Size mismatch, dev size: %lu, blobstore size: %lu\n", ctx->bs->dev->blockcnt * ctx->bs->dev->blocklen, ctx->super->size); _spdk_bs_load_ctx_fail(seq, ctx, -EILSEQ); return; - } else { - ctx->bs->total_clusters = ctx->super->size / ctx->bs->cluster_sz; + } + + if (ctx->super->size == 0) { + ctx->super->size = ctx->bs->dev->blockcnt * ctx->bs->dev->blocklen; } /* Parse the super block */ ctx->bs->clean = 1; ctx->bs->cluster_sz = ctx->super->cluster_size; + ctx->bs->total_clusters = ctx->super->size / ctx->super->cluster_size; ctx->bs->pages_per_cluster = ctx->bs->cluster_sz / SPDK_BS_PAGE_SIZE; + rc = spdk_bit_array_resize(&ctx->bs->used_clusters, ctx->bs->total_clusters); + if (rc < 0) { + _spdk_bs_load_ctx_fail(seq, ctx, -ENOMEM); + return; + } ctx->bs->md_start = ctx->super->md_start; ctx->bs->md_len = ctx->super->md_len; ctx->bs->total_data_clusters = ctx->bs->total_clusters - divide_round_up(