diff --git a/include/spdk/bdev_zone.h b/include/spdk/bdev_zone.h index 867bd2495..9306256b8 100644 --- a/include/spdk/bdev_zone.h +++ b/include/spdk/bdev_zone.h @@ -165,6 +165,32 @@ int spdk_bdev_zone_append(struct spdk_bdev_desc *desc, struct spdk_io_channel *c void *buf, uint64_t zone_id, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg); +/** + * Submit a zone_append request to the bdev. This differs from + * spdk_bdev_zone_append by allowing the data buffer to be described in a scatter + * gather list. + * + * \ingroup bdev_io_submit_functions + * + * \param desc Block device descriptor. + * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). + * \param iov A scatter gather list of buffers to be written from. + * \param iovcnt The number of elements in iov. + * \param zone_id First logical block of a zone. + * \param num_blocks The number of blocks to write. buf must be greater than or equal to this size. + * \param cb Called when the request is complete. + * \param cb_arg Argument passed to cb. + * + * \return 0 on success. On success, the callback will always + * be called (even if the request ultimately failed). + * Appended logical block address can be obtained with spdk_bdev_io_get_append_location(). + * Return negated errno on failure, in which case the callback will not be called. + * * -ENOMEM - spdk_bdev_io buffer cannot be allocated + */ +int spdk_bdev_zone_appendv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, + struct iovec *iov, int iovcnt, uint64_t zone_id, uint64_t num_blocks, + spdk_bdev_io_completion_cb cb, void *cb_arg); + /** * Submit a zone_append request with metadata to the bdev. * @@ -192,6 +218,37 @@ int spdk_bdev_zone_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_ch void *buf, void *md, uint64_t zone_id, uint64_t num_blocks, spdk_bdev_io_completion_cb cb, void *cb_arg); +/** + * Submit a zone_append request with metadata to the bdev. This differs from + * spdk_bdev_zone_append by allowing the data buffer to be described in a scatter + * gather list. + * + * This function uses separate buffer for metadata transfer (valid only if bdev supports this + * mode). + * + * \ingroup bdev_io_submit_functions + * + * \param desc Block device descriptor. + * \param ch I/O channel. Obtained by calling spdk_bdev_get_io_channel(). + * \param iov A scatter gather list of buffers to be written from. + * \param iovcnt The number of elements in iov. + * \param md Metadata buffer. + * \param zone_id First logical block of a zone. + * \param num_blocks The number of blocks to write. buf must be greater than or equal to this size. + * \param cb Called when the request is complete. + * \param cb_arg Argument passed to cb. + * + * \return 0 on success. On success, the callback will always + * be called (even if the request ultimately failed). + * Appended logical block address can be obtained with spdk_bdev_io_get_append_location(). + * Return negated errno on failure, in which case the callback will not be called. + * * -ENOMEM - spdk_bdev_io buffer cannot be allocated + */ +int spdk_bdev_zone_appendv_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, + struct iovec *iov, int iovcnt, void *md, uint64_t zone_id, + uint64_t num_blocks, spdk_bdev_io_completion_cb cb, + void *cb_arg); + /** * Get append location (offset in blocks of the bdev) for this I/O. * diff --git a/lib/bdev/bdev_zone.c b/lib/bdev/bdev_zone.c index 557e38f90..18780c2a8 100644 --- a/lib/bdev/bdev_zone.c +++ b/lib/bdev/bdev_zone.c @@ -156,6 +156,44 @@ spdk_bdev_zone_append_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channe cb, cb_arg); } +int +spdk_bdev_zone_appendv_with_md(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, + struct iovec *iov, int iovcnt, void *md_buf, uint64_t zone_id, + uint64_t num_blocks, spdk_bdev_io_completion_cb cb, + void *cb_arg) +{ + struct spdk_bdev *bdev = spdk_bdev_desc_get_bdev(desc); + struct spdk_bdev_io *bdev_io; + struct spdk_bdev_channel *channel = spdk_io_channel_get_ctx(ch); + + bdev_io = bdev_channel_get_io(channel); + if (!bdev_io) { + return -ENOMEM; + } + + bdev_io->internal.ch = channel; + bdev_io->internal.desc = desc; + bdev_io->type = SPDK_BDEV_IO_TYPE_ZONE_APPEND; + bdev_io->u.bdev.iovs = iov; + bdev_io->u.bdev.iovcnt = iovcnt; + bdev_io->u.bdev.md_buf = md_buf; + bdev_io->u.bdev.num_blocks = num_blocks; + bdev_io->u.bdev.offset_blocks = zone_id; + bdev_io_init(bdev_io, bdev, cb_arg, cb); + + bdev_io_submit(bdev_io); + return 0; +} + +int +spdk_bdev_zone_appendv(struct spdk_bdev_desc *desc, struct spdk_io_channel *ch, + struct iovec *iovs, int iovcnt, uint64_t zone_id, uint64_t num_blocks, + spdk_bdev_io_completion_cb cb, void *cb_arg) +{ + return spdk_bdev_zone_appendv_with_md(desc, ch, iovs, iovcnt, NULL, zone_id, num_blocks, + cb, cb_arg); +} + uint64_t spdk_bdev_io_get_append_location(struct spdk_bdev_io *bdev_io) {