diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index cf1b91e09..132b96cc0 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -1027,6 +1027,47 @@ raid_bdev_create(const char *name, uint32_t strip_size, uint8_t num_base_bdevs, return 0; } +/* + * brief: + * Check underlying block devices against support for metadata. Do not configure + * md support when parameters from block devices are inconsistent. + * params: + * raid_bdev - pointer to raid bdev + * returns: + * 0 - The raid bdev md parameters were successfully configured. + * non zero - Failed to configure md. + */ +static int +raid_bdev_configure_md(struct raid_bdev *raid_bdev) +{ + struct spdk_bdev *base_bdev; + uint8_t i; + + for (i = 0; i < raid_bdev->num_base_bdevs; i++) { + base_bdev = raid_bdev->base_bdev_info[i].bdev; + + if (i == 0) { + raid_bdev->bdev.md_len = spdk_bdev_get_md_size(base_bdev); + raid_bdev->bdev.md_interleave = spdk_bdev_is_md_interleaved(base_bdev); + raid_bdev->bdev.dif_type = spdk_bdev_get_dif_type(base_bdev); + raid_bdev->bdev.dif_is_head_of_md = spdk_bdev_is_dif_head_of_md(base_bdev); + raid_bdev->bdev.dif_check_flags = base_bdev->dif_check_flags; + continue; + } + + if (raid_bdev->bdev.md_len != spdk_bdev_get_md_size(base_bdev) || + raid_bdev->bdev.md_interleave != spdk_bdev_is_md_interleaved(base_bdev) || + raid_bdev->bdev.dif_type != spdk_bdev_get_dif_type(base_bdev) || + raid_bdev->bdev.dif_is_head_of_md != spdk_bdev_is_dif_head_of_md(base_bdev) || + raid_bdev->bdev.dif_check_flags != base_bdev->dif_check_flags) { + SPDK_ERRLOG("base bdevs are configured with different metadata formats\n"); + return -EPERM; + } + } + + return 0; +} + /* * brief: * If raid bdev config is complete, then only register the raid bdev to @@ -1075,6 +1116,12 @@ raid_bdev_configure(struct raid_bdev *raid_bdev) raid_bdev_gen = &raid_bdev->bdev; raid_bdev_gen->blocklen = blocklen; + rc = raid_bdev_configure_md(raid_bdev); + if (rc != 0) { + SPDK_ERRLOG("raid metadata configuration failed\n"); + return rc; + } + rc = raid_bdev->module->start(raid_bdev); if (rc != 0) { SPDK_ERRLOG("raid module startup callback failed\n"); diff --git a/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c b/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c index fade64e0b..a2eaf9bfa 100644 --- a/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c +++ b/test/unit/lib/bdev/raid/bdev_raid.c/bdev_raid_ut.c @@ -115,6 +115,11 @@ DEFINE_STUB(spdk_bdev_queue_io_wait, int, (struct spdk_bdev *bdev, struct spdk_i DEFINE_STUB(spdk_bdev_get_memory_domains, int, (struct spdk_bdev *bdev, struct spdk_memory_domain **domains, int array_size), 0); DEFINE_STUB(spdk_bdev_get_name, const char *, (const struct spdk_bdev *bdev), "test_bdev"); +DEFINE_STUB(spdk_bdev_get_md_size, uint32_t, (const struct spdk_bdev *bdev), 0); +DEFINE_STUB(spdk_bdev_is_md_interleaved, bool, (const struct spdk_bdev *bdev), false); +DEFINE_STUB(spdk_bdev_get_dif_type, enum spdk_dif_type, (const struct spdk_bdev *bdev), + SPDK_DIF_DISABLE); +DEFINE_STUB(spdk_bdev_is_dif_head_of_md, bool, (const struct spdk_bdev *bdev), false); struct spdk_io_channel * spdk_bdev_get_io_channel(struct spdk_bdev_desc *desc)