From 18f785bd2c6ce2b60e563b7778fa50e6b09d08f7 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Wed, 15 May 2019 16:27:17 +0900 Subject: [PATCH] dif: Use struct dif_sgl to simplify to create iovec array struct dif_sgl had been used only to iterate the passed iovec array. This patch utilizes struct dif_sgl and adds a helper function _dif_sgl_append() to simplify to create iovec array. _dif_sgl_append() is a static function and we have to add the callee together when we add any static function. So this patch adds both even if the patch size is a little larger. Besides, iovcnt has been used to mean the number of elements in the iovec array widely in the DIF library. So this patch changes the name of it from num_iovs to iovcnt. Change-Id: I1db4abc8ed4d2c107fe01ec6592f5f6731dc5520 Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/454558 Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris --- include/spdk/dif.h | 4 +-- lib/util/dif.c | 63 ++++++++++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/include/spdk/dif.h b/include/spdk/dif.h index 45605f4e4..6840b7791 100644 --- a/include/spdk/dif.h +++ b/include/spdk/dif.h @@ -268,7 +268,7 @@ int spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov, * during DIF insertion and strip. * * \param iovs iovec array set by this function. - * \param num_iovs Number of elements in the iovec array. + * \param iovcnt Number of elements in the iovec array. * \param buf Buffer to create extended LBA payload. * \param buf_len Length of the buffer to create extended LBA payload. * \param data_offset Offset to store the next incoming data. @@ -280,7 +280,7 @@ int spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov, * \return Number of used elements in the iovec array on success or negated * errno otherwise. */ -int spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int num_iovs, +int spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt, uint8_t *buf, uint32_t buf_len, uint32_t data_offset, uint32_t data_len, uint32_t *mapped_len, diff --git a/lib/util/dif.c b/lib/util/dif.c index 1828f5c8c..08a00ca10 100644 --- a/lib/util/dif.c +++ b/lib/util/dif.c @@ -37,16 +37,21 @@ #include "spdk/log.h" #include "spdk/util.h" -/* Context to iterate a iovec array. */ +/* Context to iterate or create a iovec array. + * Each sgl is either iterated or created at a time. + */ struct _dif_sgl { - /* Current iovec in the iteration */ + /* Current iovec in the iteration or iteration */ struct iovec *iov; - /* Remaining count of iovecs in the iteration. */ + /* Remaining count of iovecs in the iteration or iteration. */ int iovcnt; /* Current offset in the iovec */ uint32_t iov_offset; + + /* Size of the created iovec array in bytes */ + uint32_t total_size; }; static inline void @@ -55,6 +60,7 @@ _dif_sgl_init(struct _dif_sgl *s, struct iovec *iovs, int iovcnt) s->iov = iovs; s->iovcnt = iovcnt; s->iov_offset = 0; + s->total_size = 0; } static inline void @@ -95,6 +101,23 @@ _dif_sgl_fast_forward(struct _dif_sgl *s, uint32_t offset) } } +static inline bool +_dif_sgl_append(struct _dif_sgl *s, uint8_t *data, uint32_t data_len) +{ + assert(s->iovcnt > 0); + s->iov->iov_base = data; + s->iov->iov_len = data_len; + s->total_size += data_len; + s->iov++; + s->iovcnt--; + + if (s->iovcnt > 0) { + return true; + } else { + return false; + } +} + /* This function must be used before starting iteration. */ static bool _dif_sgl_is_bytes_multiple(struct _dif_sgl *s, uint32_t bytes) @@ -1263,18 +1286,17 @@ spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov, } int -spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int num_iovs, +spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt, uint8_t *buf, uint32_t buf_len, uint32_t data_offset, uint32_t data_len, uint32_t *_mapped_len, const struct spdk_dif_ctx *ctx) { - uint32_t data_block_size, head_unalign, mapped_len = 0; + uint32_t data_block_size, head_unalign; uint32_t num_blocks, offset_blocks; - struct iovec *iov = iovs; - int iovcnt = 0; + struct _dif_sgl sgl; - if (iovs == NULL || num_iovs == 0) { + if (iovs == NULL || iovcnt == 0) { return -EINVAL; } @@ -1302,37 +1324,34 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int num_iovs, offset_blocks = data_offset / data_block_size; head_unalign = data_offset % data_block_size; + _dif_sgl_init(&sgl, iovs, iovcnt); buf += offset_blocks * ctx->block_size; if (head_unalign != 0) { buf += head_unalign; - iov->iov_base = buf; - iov->iov_len = data_block_size - head_unalign; - mapped_len += data_block_size - head_unalign; - iov++; - iovcnt++; + if (!_dif_sgl_append(&sgl, buf, data_block_size - head_unalign)) { + goto end; + } buf += ctx->block_size - head_unalign; offset_blocks++; } - while (offset_blocks < num_blocks && iovcnt < num_iovs) { - iov->iov_base = buf; - iov->iov_len = data_block_size; - mapped_len += data_block_size; - iov++; - iovcnt++; - + while (offset_blocks < num_blocks) { + if (!_dif_sgl_append(&sgl, buf, data_block_size)) { + goto end; + } buf += ctx->block_size; offset_blocks++; } +end: if (_mapped_len != NULL) { - *_mapped_len = mapped_len; + *_mapped_len = sgl.total_size; } - return iovcnt; + return iovcnt - sgl.iovcnt; } int