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;