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:
parent
9a58c40eba
commit
3735f2d08e
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user