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;
|
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 *
|
static struct spdk_blob_store *
|
||||||
_spdk_bs_alloc(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts)
|
_spdk_bs_alloc(struct spdk_bs_dev *dev, struct spdk_bs_opts *opts)
|
||||||
{
|
{
|
||||||
struct spdk_blob_store *bs;
|
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));
|
bs = calloc(1, sizeof(struct spdk_blob_store));
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1698,6 +1718,7 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
|||||||
struct spdk_bs_cpl cpl;
|
struct spdk_bs_cpl cpl;
|
||||||
spdk_bs_sequence_t *seq;
|
spdk_bs_sequence_t *seq;
|
||||||
uint64_t num_md_pages;
|
uint64_t num_md_pages;
|
||||||
|
uint64_t num_md_clusters;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct spdk_bs_opts opts = {};
|
struct spdk_bs_opts opts = {};
|
||||||
int rc;
|
int rc;
|
||||||
@ -1718,6 +1739,12 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
|||||||
spdk_bs_opts_init(&opts);
|
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);
|
bs = _spdk_bs_alloc(dev, &opts);
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
dev->destroy(dev);
|
dev->destroy(dev);
|
||||||
@ -1725,7 +1752,7 @@ spdk_bs_init(struct spdk_bs_dev *dev, struct spdk_bs_opts *o,
|
|||||||
return;
|
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.
|
/* By default, allocate 1 page per cluster.
|
||||||
* Technically, this over-allocates metadata
|
* Technically, this over-allocates metadata
|
||||||
* because more metadata will reduce the number
|
* 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;
|
num_md_pages += bs->md_len;
|
||||||
|
|
||||||
ctx->super->crc = _spdk_blob_md_page_calc_crc(ctx->super);
|
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 */
|
/* 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);
|
_spdk_bs_claim_cluster(bs, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -962,6 +962,30 @@ bs_cluster_sz(void)
|
|||||||
struct spdk_bs_opts opts;
|
struct spdk_bs_opts opts;
|
||||||
uint32_t cluster_sz;
|
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();
|
dev = init_dev();
|
||||||
spdk_bs_opts_init(&opts);
|
spdk_bs_opts_init(&opts);
|
||||||
opts.cluster_sz *= 2;
|
opts.cluster_sz *= 2;
|
||||||
|
Loading…
Reference in New Issue
Block a user