diff --git a/module/bdev/raid/bdev_raid.c b/module/bdev/raid/bdev_raid.c index e88418520..0ea557fab 100644 --- a/module/bdev/raid/bdev_raid.c +++ b/module/bdev/raid/bdev_raid.c @@ -91,6 +91,7 @@ raid_bdev_create_cb(void *io_device, void *ctx_buf) struct raid_bdev *raid_bdev = io_device; struct raid_bdev_io_channel *raid_ch = ctx_buf; uint8_t i; + int ret = 0; SPDK_DEBUGLOG(bdev_raid, "raid_bdev_create_cb, %p\n", raid_ch); @@ -114,19 +115,30 @@ raid_bdev_create_cb(void *io_device, void *ctx_buf) raid_ch->base_channel[i] = spdk_bdev_get_io_channel( raid_bdev->base_bdev_info[i].desc); if (!raid_ch->base_channel[i]) { - uint8_t j; - - for (j = 0; j < i; j++) { - spdk_put_io_channel(raid_ch->base_channel[j]); - } - free(raid_ch->base_channel); - raid_ch->base_channel = NULL; SPDK_ERRLOG("Unable to create io channel for base bdev\n"); - return -ENOMEM; + ret = -ENOMEM; + break; } } - return 0; + if (!ret && raid_bdev->module->get_io_channel) { + raid_ch->module_channel = raid_bdev->module->get_io_channel(raid_bdev); + if (!raid_ch->module_channel) { + SPDK_ERRLOG("Unable to create io channel for raid module\n"); + ret = -ENOMEM; + } + } + + if (ret) { + uint8_t j; + + for (j = 0; j < i; j++) { + spdk_put_io_channel(raid_ch->base_channel[j]); + } + free(raid_ch->base_channel); + raid_ch->base_channel = NULL; + } + return ret; } /* @@ -149,6 +161,11 @@ raid_bdev_destroy_cb(void *io_device, void *ctx_buf) assert(raid_ch != NULL); assert(raid_ch->base_channel); + + if (raid_ch->module_channel) { + spdk_put_io_channel(raid_ch->module_channel); + } + for (i = 0; i < raid_ch->num_channels; i++) { /* Free base bdev channels */ assert(raid_ch->base_channel[i] != NULL); diff --git a/module/bdev/raid/bdev_raid.h b/module/bdev/raid/bdev_raid.h index 5c253ab28..7f3f40399 100644 --- a/module/bdev/raid/bdev_raid.h +++ b/module/bdev/raid/bdev_raid.h @@ -199,6 +199,9 @@ struct raid_bdev_io_channel { /* Number of IO channels */ uint8_t num_channels; + + /* Private raid module IO channel */ + struct spdk_io_channel *module_channel; }; /* TAIL heads for various raid bdev lists */ @@ -265,6 +268,12 @@ struct raid_bdev_module { /* Handler for requests without payload (flush, unmap). Optional. */ void (*submit_null_payload_request)(struct raid_bdev_io *raid_io); + /* + * Called when the bdev's IO channel is created to get the module's private IO channel. + * Optional. + */ + struct spdk_io_channel *(*get_io_channel)(struct raid_bdev *raid_bdev); + TAILQ_ENTRY(raid_bdev_module) link; };