blobstore: verify options passed to spdk_bs_init

Three checks are added to options passed to spdk_bs_init,
with appropriate errors returned:
- whether any of the options is set to 0
- device size has to be bigger than cluster size
- pages reserved for metadata exceed total number of clusters

Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: Idee3c194b653e737ec7c7a768f1973ff72452c5b
Reviewed-on: https://review.gerrithub.io/379676
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Tomasz Zawadzki 2017-09-25 12:07:34 +02:00 committed by Daniel Verkamp
parent 9a58c40eba
commit 3735f2d08e
2 changed files with 65 additions and 2 deletions

View File

@ -1367,11 +1367,31 @@ spdk_bs_opts_init(struct spdk_bs_opts *opts)
opts->max_channel_ops = SPDK_BLOB_OPTS_MAX_CHANNEL_OPS;
}
static int
_spdk_bs_opts_verify(struct spdk_bs_opts *opts)
{
if (opts->cluster_sz == 0 || opts->num_md_pages == 0 || opts->max_md_ops == 0 ||
opts->max_channel_ops == 0) {
SPDK_ERRLOG("Blobstore options cannot be set to 0\n");
return -1;
}
return 0;
}
static struct spdk_blob_store *
_spdk_bs_alloc(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts)
{
struct spdk_blob_store *bs;
uint64_t dev_size;
dev_size = dev->blocklen * dev->blockcnt;
if (dev_size < opts->cluster_sz) {
/* Device size cannot be smaller than cluster size of blobstore */
SPDK_ERRLOG("Device size %" PRIu64 " is smaller than cluster size %d\n", dev_size,
opts->cluster_sz);
return NULL;
}
bs = calloc(1, sizeof(struct spdk_blob_store));
if (!bs) {
return NULL;
@ -1698,6 +1718,7 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
struct spdk_bs_cpl cpl;
spdk_bs_sequence_t *seq;
uint64_t num_md_pages;
uint64_t num_md_clusters;
uint32_t i;
struct spdk_bs_opts opts = {};
int rc;
@ -1718,6 +1739,12 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
spdk_bs_opts_init(&opts);
}
if (_spdk_bs_opts_verify(&opts) != 0) {
dev->destroy(dev);
cb_fn(cb_arg, NULL, -EINVAL);
return;
}
bs = _spdk_bs_alloc(dev, &opts);
if (!bs) {
dev->destroy(dev);
@ -1725,7 +1752,7 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
return;
}
if (opts.num_md_pages == UINT32_MAX) {
if (opts.num_md_pages == SPDK_BLOB_OPTS_NUM_MD_PAGES) {
/* By default, allocate 1 page per cluster.
* Technically, this over-allocates metadata
* because more metadata will reduce the number
@ -1799,8 +1826,20 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
num_md_pages += bs->md_len;
ctx->super->crc = _spdk_blob_md_page_calc_crc(ctx->super);
num_md_clusters = divide_round_up(num_md_pages, bs->pages_per_cluster);
if (num_md_clusters > bs->total_clusters) {
SPDK_ERRLOG("Blobstore metadata cannot use more clusters than is available, "
"please decrease number of pages reserved for metadata "
"or increase cluster size.\n");
spdk_dma_free(ctx->super);
free(ctx);
_spdk_bs_free(bs);
cb_fn(cb_arg, NULL, -ENOMEM);
return;
}
/* Claim all of the clusters used by the metadata */
for (i = 0; i < divide_round_up(num_md_pages, bs->pages_per_cluster); i++) {
for (i = 0; i < num_md_clusters; i++) {
_spdk_bs_claim_cluster(bs, i);
}

View File

@ -962,6 +962,30 @@ bs_cluster_sz(void)
struct spdk_bs_opts opts;
uint32_t cluster_sz;
/* Set cluster size to zero */
dev = init_dev();
spdk_bs_opts_init(&opts);
opts.cluster_sz = 0;
/* Initialize a new blob store */
spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == -EINVAL);
SPDK_CU_ASSERT_FATAL(g_bs == NULL);
/*
* Set cluster size to blobstore page size,
* to work it is required to be at least twice the blobstore page size.
*/
dev = init_dev();
spdk_bs_opts_init(&opts);
opts.cluster_sz = SPDK_BS_PAGE_SIZE;
/* Initialize a new blob store */
spdk_bs_init(dev, &opts, bs_op_with_handle_complete, NULL);
CU_ASSERT(g_bserrno == -ENOMEM);
SPDK_CU_ASSERT_FATAL(g_bs == NULL);
/* Set cluster size to twice the default */
dev = init_dev();
spdk_bs_opts_init(&opts);
opts.cluster_sz *= 2;