From d683d7b792f429d68aa71f34f5fb5f00f8df339d Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Fri, 21 Oct 2022 20:41:57 +0900 Subject: [PATCH] bdev/part: Modify spdk_bdev_part_submit_request() to use custom completion callback In the following patches, we will add a feature to inject data corruption to the error bdev module. For read I/O, we will have to inject data corruption at completion. However, if we use spdk_bdev_part_submit_request(), it will not be possible because we cannot add any custom operation into the completion callback. To fix the issue, modify spdk_+bdev_part_submit_request() and rename it to spdk_bdev_part_submit_request_ext(). Fortunately, we can use stored_user_cb in struct spdk_bdev_io. Signed-off-by: Shuhei Matsumoto Change-Id: I46d3c40ea88a3fedd8a8fef6b68ee417c814a7a1 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15002 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Aleksey Marchuk --- CHANGELOG.md | 2 ++ include/spdk/bdev_module.h | 19 +++++++++++++++++++ lib/bdev/part.c | 23 ++++++++++++++++++++--- lib/bdev/spdk_bdev.map | 1 + 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0a9d58b6..6a3c19690 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Both of interleaved and separated metadata are now supported by the malloc bdev Protection information is now supported by the malloc bdev module. +A new API `spkd_bdev_part_submit_request_ext` was added to specify a custom completion callback. + ### scheduler Changing scheduler from dynamic back to static is no longer possible, diff --git a/include/spdk/bdev_module.h b/include/spdk/bdev_module.h index 8e13e0b39..d598d05d6 100644 --- a/include/spdk/bdev_module.h +++ b/include/spdk/bdev_module.h @@ -1287,6 +1287,25 @@ int spdk_bdev_part_construct(struct spdk_bdev_part *part, struct spdk_bdev_part_ */ int spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io); +/** + * Forwards I/O from an spdk_bdev_part to the underlying base bdev. + * + * This function will apply the offset_blocks the user provided to + * spdk_bdev_part_construct to the I/O. The user should not manually + * apply this offset before submitting any I/O through this function. + * + * This function enables user to specify a completion callback. It is required that + * the completion callback calls spdk_bdev_io_complete() for the forwarded I/O. + * + * \param ch The I/O channel associated with the spdk_bdev_part. + * \param bdev_io The I/O to be submitted to the underlying bdev. + * \param cb Called when the forwarded I/O completes. + * \return 0 on success or non-zero if submit request failed. + */ +int spdk_bdev_part_submit_request_ext(struct spdk_bdev_part_channel *ch, + struct spdk_bdev_io *bdev_io, + spdk_bdev_io_completion_cb cb); + /** * Return a pointer to this part's spdk_bdev. * diff --git a/lib/bdev/part.c b/lib/bdev/part.c index f9fda7fcc..c186eb530 100644 --- a/lib/bdev/part.c +++ b/lib/bdev/part.c @@ -238,6 +238,7 @@ bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) { struct spdk_bdev_io *part_io = cb_arg; uint32_t offset, remapped_offset; + spdk_bdev_io_completion_cb cb; int rc, status; switch (bdev_io->type) { @@ -260,14 +261,22 @@ bdev_part_complete_io(struct spdk_bdev_io *bdev_io, bool success, void *cb_arg) break; } - status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; - spdk_bdev_io_complete(part_io, status); + cb = part_io->u.bdev.stored_user_cb; + if (cb != NULL) { + cb(part_io, success, NULL); + } else { + status = success ? SPDK_BDEV_IO_STATUS_SUCCESS : SPDK_BDEV_IO_STATUS_FAILED; + + spdk_bdev_io_complete(part_io, status); + } + spdk_bdev_free_io(bdev_io); } int -spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io) +spdk_bdev_part_submit_request_ext(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io, + spdk_bdev_io_completion_cb cb) { struct spdk_bdev_part *part = ch->part; struct spdk_io_channel *base_ch = ch->base_ch; @@ -275,6 +284,8 @@ spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bde uint64_t offset, remapped_offset, remapped_src_offset; int rc = 0; + bdev_io->u.bdev.stored_user_cb = cb; + offset = bdev_io->u.bdev.offset_blocks; remapped_offset = offset + part->internal.offset_blocks; @@ -382,6 +393,12 @@ spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bde return rc; } +int +spdk_bdev_part_submit_request(struct spdk_bdev_part_channel *ch, struct spdk_bdev_io *bdev_io) +{ + return spdk_bdev_part_submit_request_ext(ch, bdev_io, NULL); +} + static int bdev_part_channel_create_cb(void *io_device, void *ctx_buf) { diff --git a/lib/bdev/spdk_bdev.map b/lib/bdev/spdk_bdev.map index 8e708e59f..c04cc7dc6 100644 --- a/lib/bdev/spdk_bdev.map +++ b/lib/bdev/spdk_bdev.map @@ -149,6 +149,7 @@ spdk_bdev_part_base_construct_ext; spdk_bdev_part_construct; spdk_bdev_part_submit_request; + spdk_bdev_part_submit_request_ext; spdk_bdev_part_get_bdev; spdk_bdev_part_get_base; spdk_bdev_part_get_base_bdev;