blobstore: Save the original size of the disk.

Save the original size of the disk to metadata when it is first created.
On load verify that the disk did not change size.

Signed-off-by: Piotr Pelplinski <piotr.pelplinski@intel.com>
Change-Id: I535940ee188425ee3b394effd99653cc073d541e

Reviewed-on: https://review.gerrithub.io/410896
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Piotr Pelplinski 2018-05-10 14:12:36 +02:00 committed by Daniel Verkamp
parent cf930a450b
commit 2c91e91907
3 changed files with 70 additions and 3 deletions

View File

@ -1465,6 +1465,9 @@ _spdk_blob_persist_dirty(spdk_bs_sequence_t *seq, void *cb_arg, int bserrno)
struct spdk_blob_persist_ctx *ctx = cb_arg;
ctx->super->clean = 0;
if (ctx->super->size == 0) {
ctx->super->size = ctx->blob->bs->dev->blockcnt * ctx->blob->bs->dev->blocklen;
}
_spdk_bs_write_super(seq, ctx->blob->bs, ctx->super, _spdk_blob_persist_dirty_cpl, ctx);
}
@ -3068,10 +3071,21 @@ _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) {
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;
}
/* Parse the super block */
ctx->bs->clean = 1;
ctx->bs->cluster_sz = ctx->super->cluster_size;
ctx->bs->total_clusters = ctx->bs->dev->blockcnt / (ctx->bs->cluster_sz / ctx->bs->dev->blocklen);
ctx->bs->pages_per_cluster = ctx->bs->cluster_sz / SPDK_BS_PAGE_SIZE;
ctx->bs->md_start = ctx->super->md_start;
ctx->bs->md_len = ctx->super->md_len;
@ -3599,6 +3613,8 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
num_md_lba = _spdk_bs_page_to_lba(bs, num_md_pages);
ctx->super->size = dev->blockcnt * dev->blocklen;
ctx->super->crc = _spdk_blob_md_page_calc_crc(ctx->super);
num_md_clusters = divide_round_up(num_md_pages, bs->pages_per_cluster);

View File

@ -344,7 +344,9 @@ struct spdk_bs_super_block {
uint32_t used_blobid_mask_start; /* Offset from beginning of disk, in pages */
uint32_t used_blobid_mask_len; /* Count, in pages */
uint8_t reserved[4012];
uint64_t size; /* size of blobstore in bytes */
uint8_t reserved[4004];
uint32_t crc;
};
SPDK_STATIC_ASSERT(sizeof(struct spdk_bs_super_block) == 0x1000, "Invalid super block size");

View File

@ -1991,6 +1991,7 @@ bs_load(void)
super_block = (struct spdk_bs_super_block *)g_dev_buffer;
CU_ASSERT(super_block->clean == 1);
CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
spdk_bs_open_blob(g_bs, blobid, blob_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
@ -2018,11 +2019,59 @@ bs_load(void)
CU_ASSERT(g_bserrno == 0);
blob = NULL;
g_blob = NULL;
g_blobid = SPDK_BLOBID_INVALID;
spdk_bs_unload(g_bs, bs_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
g_bs = NULL;
/* Load should fail: bdev size < saved size */
dev = init_dev();
dev->blockcnt /= 2;
spdk_bs_opts_init(&opts);
snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == -EILSEQ);
/* Load should succeed: bdev size > saved size */
dev = init_dev();
dev->blockcnt *= 4;
spdk_bs_opts_init(&opts);
snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
spdk_bs_unload(g_bs, bs_op_complete, NULL);
/* Test compatibility mode */
dev = init_dev();
super_block->size = 0;
super_block->crc = _spdk_blob_md_page_calc_crc(super_block);
spdk_bs_opts_init(&opts);
snprintf(opts.bstype.bstype, sizeof(opts.bstype.bstype), "TESTTYPE");
spdk_bs_load(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == 0);
SPDK_CU_ASSERT_FATAL(g_bs != NULL);
/* Create a blob */
spdk_bs_create_blob(g_bs, blob_op_with_id_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(g_blobid != SPDK_BLOBID_INVALID);
/* Blobstore should update number of blocks in super_block */
CU_ASSERT(super_block->size == dev->blockcnt * dev->blocklen);
CU_ASSERT(super_block->clean == 0);
spdk_bs_unload(g_bs, bs_op_complete, NULL);
CU_ASSERT(g_bserrno == 0);
CU_ASSERT(super_block->clean == 1);
g_bs = NULL;
}
static void