From 706029d5be4c1fb5fbfecb4a65468cdf55993b8d Mon Sep 17 00:00:00 2001 From: Artur Paszkiewicz Date: Wed, 9 Oct 2019 11:22:41 +0200 Subject: [PATCH] module/raid: register RAID modules Add the ability to register RAID modules. Supported RAID levels are determined based on the list of registered modules. The module descriptor structure will hold the function pointers for RAID-level specific operations. Signed-off-by: Artur Paszkiewicz Change-Id: I7a579ac381f1764b427a48d1dc31260725217c4e Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/471080 Tested-by: SPDK CI Jenkins Reviewed-by: Shuhei Matsumoto Reviewed-by: Jim Harris --- module/bdev/raid/bdev_raid.c | 43 ++++++++++++++++++++++++++---------- module/bdev/raid/bdev_raid.h | 25 +++++++++++++++++++++ module/bdev/raid/raid0.c | 5 +++++ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index 01748d8a1..db6a24b6f 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -66,6 +66,32 @@ struct raid_all_tailq g_raid_bdev_list = TAILQ_HEAD_INITIALIZER(g_raid_bdev_lis struct raid_offline_tailq g_raid_bdev_offline_list = TAILQ_HEAD_INITIALIZER( g_raid_bdev_offline_list); +static TAILQ_HEAD(, raid_bdev_module) g_raid_modules = TAILQ_HEAD_INITIALIZER(g_raid_modules); + +static struct raid_bdev_module *raid_bdev_module_find(enum raid_level level) +{ + struct raid_bdev_module *raid_module; + + TAILQ_FOREACH(raid_module, &g_raid_modules, link) { + if (raid_module->level == level) { + return raid_module; + } + } + + return NULL; +} + +void raid_bdev_module_list_add(struct raid_bdev_module *raid_module) +{ + if (raid_bdev_module_find(raid_module->level) != NULL) { + SPDK_ERRLOG("module for raid level '%s' already registered.\n", + raid_bdev_level_to_str(raid_module->level)); + assert(false); + } else { + TAILQ_INSERT_TAIL(&g_raid_modules, raid_module, link); + } +} + /* Function declarations */ static void raid_bdev_examine(struct spdk_bdev *bdev); static int raid_bdev_init(void); @@ -722,7 +748,7 @@ raid_bdev_config_find_by_name(const char *raid_name) * raid_name - name for raid bdev. * strip_size - strip size in KB * num_base_bdevs - number of base bdevs. - * level - raid level, only raid level 0 is supported. + * level - raid level. * _raid_cfg - Pointer to newly added configuration */ int @@ -748,12 +774,6 @@ raid_bdev_config_add(const char *raid_name, uint32_t strip_size, uint8_t num_bas return -EINVAL; } - if (level != RAID0) { - SPDK_ERRLOG("invalid raid level %u, only raid level 0 is supported\n", - level); - return -EINVAL; - } - raid_cfg = calloc(1, sizeof(*raid_cfg)); if (raid_cfg == NULL) { SPDK_ERRLOG("unable to allocate memory\n"); @@ -1220,11 +1240,10 @@ raid_bdev_create(struct raid_bdev_config *raid_cfg) raid_bdev->config = raid_cfg; raid_bdev->level = raid_cfg->level; - switch (raid_bdev->level) { - case RAID0: - break; - default: - SPDK_ERRLOG("invalid raid level %u\n", raid_bdev->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; } diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index a26eb362d..31194f885 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -153,6 +153,9 @@ struct raid_bdev { /* Set to true if destroy of this raid bdev is started. */ bool destroy_started; + + /* Module for RAID-level specific operations */ + struct raid_bdev_module *module; }; /* @@ -240,6 +243,28 @@ struct raid_bdev_config *raid_bdev_config_find_by_name(const char *raid_name); enum raid_level raid_bdev_parse_raid_level(const char *str); const char *raid_bdev_level_to_str(enum raid_level level); +/* + * RAID module descriptor + */ +struct raid_bdev_module { + /* RAID level implemented by this module */ + enum raid_level level; + + TAILQ_ENTRY(raid_bdev_module) link; +}; + +void raid_bdev_module_list_add(struct raid_bdev_module *raid_module); + +#define __RAID_MODULE_REGISTER(line) __RAID_MODULE_REGISTER_(line) +#define __RAID_MODULE_REGISTER_(line) raid_module_register_##line + +#define RAID_MODULE_REGISTER(_module) \ +__attribute__((constructor)) static void \ +__RAID_MODULE_REGISTER(__LINE__)(void) \ +{ \ + raid_bdev_module_list_add(_module); \ +} + void raid0_start_rw_request(struct spdk_io_channel *ch, struct spdk_bdev_io *bdev_io); void diff --git a/module/bdev/raid/raid0.c b/module/bdev/raid/raid0.c index 9e0907c52..ce9335a64 100644 --- a/module/bdev/raid/raid0.c +++ b/module/bdev/raid/raid0.c @@ -358,4 +358,9 @@ raid0_submit_null_payload_request(void *_bdev_io) } } +static struct raid_bdev_module g_raid0_module = { + .level = RAID0, +}; +RAID_MODULE_REGISTER(&g_raid0_module) + SPDK_LOG_REGISTER_COMPONENT("bdev_raid0", SPDK_LOG_BDEV_RAID0)