From 0a5194fadcb6dd76aa3cb91a828fb8d54d13274e Mon Sep 17 00:00:00 2001 From: Artur Paszkiewicz Date: Thu, 7 Nov 2019 09:19:19 +0100 Subject: [PATCH] module/raid: check for the minimum required base bdevs Define the minimum number of base devices required for a raid level in struct raid_module and check that when starting the array. Change-Id: Ic70d107721e0df48ef8d9406132c103eee3cc9d4 Signed-off-by: Artur Paszkiewicz Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/851 Reviewed-by: Paul Luse Reviewed-by: Shuhei Matsumoto Reviewed-by: Tomasz Zawadzki Reviewed-by: Darek Stojaczyk Tested-by: SPDK CI Jenkins --- module/bdev/raid/bdev_raid.c | 25 ++++++++++++++++--------- module/bdev/raid/bdev_raid.h | 3 +++ module/bdev/raid/raid0.c | 1 + 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index 310a85006..9015aa0a2 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -1179,6 +1179,21 @@ raid_bdev_create(struct raid_bdev_config *raid_cfg) { struct raid_bdev *raid_bdev; struct spdk_bdev *raid_bdev_gen; + struct raid_bdev_module *module; + + module = raid_bdev_module_find(raid_cfg->level); + if (module == NULL) { + SPDK_ERRLOG("Unsupported raid level '%d'\n", raid_cfg->level); + return -EINVAL; + } + + assert(module->base_bdevs_min != 0); + if (raid_cfg->num_base_bdevs < module->base_bdevs_min) { + SPDK_ERRLOG("At least %u base devices required for %s\n", + module->base_bdevs_min, + raid_bdev_level_to_str(raid_cfg->level)); + return -EINVAL; + } raid_bdev = calloc(1, sizeof(*raid_bdev)); if (!raid_bdev) { @@ -1186,7 +1201,7 @@ raid_bdev_create(struct raid_bdev_config *raid_cfg) return -ENOMEM; } - assert(raid_cfg->num_base_bdevs != 0); + raid_bdev->module = module; raid_bdev->num_base_bdevs = raid_cfg->num_base_bdevs; raid_bdev->base_bdev_info = calloc(raid_bdev->num_base_bdevs, sizeof(struct raid_base_bdev_info)); @@ -1205,14 +1220,6 @@ raid_bdev_create(struct raid_bdev_config *raid_cfg) raid_bdev->config = raid_cfg; raid_bdev->level = raid_cfg->level; - raid_bdev->module = raid_bdev_module_find(raid_bdev->level); - if (raid_bdev->module == NULL) { - SPDK_ERRLOG("Unsupported raid level '%d'\n", raid_bdev->level); - free(raid_bdev->base_bdev_info); - free(raid_bdev); - return -EINVAL; - } - raid_bdev_gen = &raid_bdev->bdev; raid_bdev_gen->name = strdup(raid_cfg->name); diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index a4f6cbb5c..125229947 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -256,6 +256,9 @@ struct raid_bdev_module { /* RAID level implemented by this module */ enum raid_level level; + /* Minimum required number of base bdevs. Must be > 0. */ + uint8_t base_bdevs_min; + /* * Called when the raid is starting, right before changing the state to * online and registering the bdev. Parameters of the bdev like blockcnt diff --git a/module/bdev/raid/raid0.c b/module/bdev/raid/raid0.c index e9b079e12..7ed26c5ed 100644 --- a/module/bdev/raid/raid0.c +++ b/module/bdev/raid/raid0.c @@ -374,6 +374,7 @@ static int raid0_start(struct raid_bdev *raid_bdev) static struct raid_bdev_module g_raid0_module = { .level = RAID0, + .base_bdevs_min = 1, .start = raid0_start, .submit_rw_request = raid0_submit_rw_request, .submit_null_payload_request = raid0_submit_null_payload_request,