diff --git a/include/spdk_internal/nvme_tcp.h b/include/spdk_internal/nvme_tcp.h index 3345880c1b..01f0ad8a1c 100644 --- a/include/spdk_internal/nvme_tcp.h +++ b/include/spdk_internal/nvme_tcp.h @@ -38,6 +38,8 @@ #include "spdk/sock.h" #include "spdk/dif.h" +#include "sgl.h" + #define SPDK_CRC32C_XOR 0xffffffffUL #define SPDK_NVME_TCP_DIGEST_LEN 4 #define SPDK_NVME_TCP_DIGEST_ALIGNMENT 4 @@ -76,13 +78,6 @@ typedef void (*nvme_tcp_qpair_xfer_complete_cb)(void *cb_arg); -struct _nvme_tcp_sgl { - struct iovec *iov; - int iovcnt; - uint32_t iov_offset; - uint32_t total_size; -}; - struct nvme_tcp_pdu { union { /* to hold error pdu data */ @@ -125,7 +120,7 @@ struct nvme_tcp_pdu { TAILQ_ENTRY(nvme_tcp_pdu) tailq; uint32_t remaining; uint32_t padding_len; - struct _nvme_tcp_sgl sgl; + struct spdk_iov_sgl sgl; struct spdk_dif_ctx *dif_ctx; @@ -248,32 +243,7 @@ nvme_tcp_pdu_calc_data_digest(struct nvme_tcp_pdu *pdu) } static inline void -_nvme_tcp_sgl_init(struct _nvme_tcp_sgl *s, struct iovec *iov, int iovcnt, - uint32_t iov_offset) -{ - s->iov = iov; - s->iovcnt = iovcnt; - s->iov_offset = iov_offset; - s->total_size = 0; -} - -static inline void -_nvme_tcp_sgl_advance(struct _nvme_tcp_sgl *s, uint32_t step) -{ - s->iov_offset += step; - while (s->iovcnt > 0) { - if (s->iov_offset < s->iov->iov_len) { - break; - } - - s->iov_offset -= s->iov->iov_len; - s->iov++; - s->iovcnt--; - } -} - -static inline void -_nvme_tcp_sgl_get_buf(struct _nvme_tcp_sgl *s, void **_buf, uint32_t *_buf_len) +_nvme_tcp_sgl_get_buf(struct spdk_iov_sgl *s, void **_buf, uint32_t *_buf_len) { if (_buf != NULL) { *_buf = s->iov->iov_base + s->iov_offset; @@ -284,33 +254,12 @@ _nvme_tcp_sgl_get_buf(struct _nvme_tcp_sgl *s, void **_buf, uint32_t *_buf_len) } static inline bool -_nvme_tcp_sgl_append(struct _nvme_tcp_sgl *s, uint8_t *data, uint32_t data_len) -{ - if (s->iov_offset >= data_len) { - s->iov_offset -= data_len; - } else { - assert(s->iovcnt > 0); - s->iov->iov_base = data + s->iov_offset; - s->iov->iov_len = data_len - s->iov_offset; - s->total_size += data_len - s->iov_offset; - s->iov_offset = 0; - s->iov++; - s->iovcnt--; - if (s->iovcnt == 0) { - return false; - } - } - - return true; -} - -static inline bool -_nvme_tcp_sgl_append_multi(struct _nvme_tcp_sgl *s, struct iovec *iov, int iovcnt) +_nvme_tcp_sgl_append_multi(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt) { int i; for (i = 0; i < iovcnt; i++) { - if (!_nvme_tcp_sgl_append(s, iov[i].iov_base, iov[i].iov_len)) { + if (!spdk_iov_sgl_append(s, iov[i].iov_base, iov[i].iov_len)) { return false; } } @@ -332,7 +281,7 @@ _get_iov_array_size(struct iovec *iov, int iovcnt) } static inline bool -_nvme_tcp_sgl_append_multi_with_md(struct _nvme_tcp_sgl *s, struct iovec *iov, int iovcnt, +_nvme_tcp_sgl_append_multi_with_md(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt, uint32_t data_len, const struct spdk_dif_ctx *dif_ctx) { int rc; @@ -368,14 +317,14 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu, bool hdgst_enable, bool ddgst_enable, uint32_t *_mapped_length) { uint32_t hlen, plen; - struct _nvme_tcp_sgl *sgl; + struct spdk_iov_sgl *sgl; if (iovcnt == 0) { return 0; } sgl = &pdu->sgl; - _nvme_tcp_sgl_init(sgl, iov, iovcnt, 0); + spdk_iov_sgl_init(sgl, iov, iovcnt, 0); hlen = pdu->hdr.common.hlen; /* Header Digest */ @@ -386,7 +335,7 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu, plen = hlen; if (!pdu->data_len) { /* PDU header + possible header digest */ - _nvme_tcp_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen); + spdk_iov_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen); goto end; } @@ -396,7 +345,7 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu, plen = hlen; } - if (!_nvme_tcp_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen)) { + if (!spdk_iov_sgl_append(sgl, (uint8_t *)&pdu->hdr.raw, hlen)) { goto end; } @@ -416,7 +365,7 @@ nvme_tcp_build_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu, /* Data Digest */ if (g_nvme_tcp_ddgst[pdu->hdr.common.pdu_type] && ddgst_enable) { plen += SPDK_NVME_TCP_DIGEST_LEN; - _nvme_tcp_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN); + spdk_iov_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN); } assert(plen == pdu->hdr.common.plen); @@ -433,14 +382,14 @@ static int nvme_tcp_build_payload_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu *pdu, bool ddgst_enable, uint32_t *_mapped_length) { - struct _nvme_tcp_sgl *sgl; + struct spdk_iov_sgl *sgl; if (iovcnt == 0) { return 0; } sgl = &pdu->sgl; - _nvme_tcp_sgl_init(sgl, iov, iovcnt, pdu->rw_offset); + spdk_iov_sgl_init(sgl, iov, iovcnt, pdu->rw_offset); if (spdk_likely(!pdu->dif_ctx)) { if (!_nvme_tcp_sgl_append_multi(sgl, pdu->data_iov, pdu->data_iovcnt)) { @@ -455,7 +404,7 @@ nvme_tcp_build_payload_iovs(struct iovec *iov, int iovcnt, struct nvme_tcp_pdu * /* Data Digest */ if (ddgst_enable) { - _nvme_tcp_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN); + spdk_iov_sgl_append(sgl, pdu->data_digest, SPDK_NVME_TCP_DIGEST_LEN); } end: @@ -565,7 +514,7 @@ nvme_tcp_pdu_set_data_buf(struct nvme_tcp_pdu *pdu, { uint32_t buf_offset, buf_len, remain_len, len; uint8_t *buf; - struct _nvme_tcp_sgl *pdu_sgl, buf_sgl; + struct spdk_iov_sgl *pdu_sgl, buf_sgl; pdu->data_len = data_len; @@ -583,20 +532,20 @@ nvme_tcp_pdu_set_data_buf(struct nvme_tcp_pdu *pdu, } else { pdu_sgl = &pdu->sgl; - _nvme_tcp_sgl_init(pdu_sgl, pdu->data_iov, NVME_TCP_MAX_SGL_DESCRIPTORS, 0); - _nvme_tcp_sgl_init(&buf_sgl, iov, iovcnt, 0); + spdk_iov_sgl_init(pdu_sgl, pdu->data_iov, NVME_TCP_MAX_SGL_DESCRIPTORS, 0); + spdk_iov_sgl_init(&buf_sgl, iov, iovcnt, 0); - _nvme_tcp_sgl_advance(&buf_sgl, buf_offset); + spdk_iov_sgl_advance(&buf_sgl, buf_offset); remain_len = buf_len; while (remain_len > 0) { _nvme_tcp_sgl_get_buf(&buf_sgl, (void *)&buf, &len); len = spdk_min(len, remain_len); - _nvme_tcp_sgl_advance(&buf_sgl, len); + spdk_iov_sgl_advance(&buf_sgl, len); remain_len -= len; - if (!_nvme_tcp_sgl_append(pdu_sgl, buf, len)) { + if (!spdk_iov_sgl_append(pdu_sgl, buf, len)) { break; } } diff --git a/include/spdk_internal/sgl.h b/include/spdk_internal/sgl.h new file mode 100644 index 0000000000..9fee65d425 --- /dev/null +++ b/include/spdk_internal/sgl.h @@ -0,0 +1,127 @@ +/*- + * BSD LICENSE + * + * Copyright (c) Intel Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SGL_INTERNAL_H__ +#define __SGL_INTERNAL_H__ + +#include "spdk/stdinc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct spdk_iov_sgl { + struct iovec *iov; + int iovcnt; + uint32_t iov_offset; + uint32_t total_size; +}; + +/** + * Initialize struct spdk_iov_sgl with iov, iovcnt and iov_offset. + * + * \param s the spdk_iov_sgl to be filled. + * \param iov the io vector to fill the s + * \param iovcnt the size the iov + * \param iov_offset the current filled iov_offset for s. + */ + +static inline void +spdk_iov_sgl_init(struct spdk_iov_sgl *s, struct iovec *iov, int iovcnt, + uint32_t iov_offset) +{ + s->iov = iov; + s->iovcnt = iovcnt; + s->iov_offset = iov_offset; + s->total_size = 0; +} + +/** + * Consume the iovs in spdk_iov_sgl with passed bytes + * + * \param s the spdk_iov_sgl which contains the iov + * \param step the bytes_size consumed. + */ + +static inline void +spdk_iov_sgl_advance(struct spdk_iov_sgl *s, uint32_t step) +{ + s->iov_offset += step; + while (s->iovcnt > 0) { + assert(s->iov != NULL); + if (s->iov_offset < s->iov->iov_len) { + break; + } + + s->iov_offset -= s->iov->iov_len; + s->iov++; + s->iovcnt--; + } +} + +/** + * Append the data to the struct spdk_iov_sgl pointed by s + * + * \param s the address of the struct spdk_iov_sgl + * \param data the data buffer to be appended + * \param data_len the length of the data. + * + * \return true if all the data is appended. + */ + +static inline bool +spdk_iov_sgl_append(struct spdk_iov_sgl *s, uint8_t *data, uint32_t data_len) +{ + if (s->iov_offset >= data_len) { + s->iov_offset -= data_len; + } else { + assert(s->iovcnt > 0); + s->iov->iov_base = data + s->iov_offset; + s->iov->iov_len = data_len - s->iov_offset; + s->total_size += data_len - s->iov_offset; + s->iov_offset = 0; + s->iov++; + s->iovcnt--; + if (s->iovcnt == 0) { + return false; + } + } + + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __SGL_INTERNAL_H__ */ diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index dcd2aa3954..842e167d7b 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -57,6 +57,8 @@ #include "spdk/log.h" +#include "spdk_internal/sgl.h" + #define MAX_TMPBUF 1024 #ifdef __FreeBSD__ @@ -387,49 +389,11 @@ iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn, } } -struct _iscsi_sgl { - struct iovec *iov; - int iovcnt; - uint32_t iov_offset; - uint32_t total_size; -}; - -static inline void -_iscsi_sgl_init(struct _iscsi_sgl *s, struct iovec *iovs, int iovcnt, - uint32_t iov_offset) -{ - s->iov = iovs; - s->iovcnt = iovcnt; - s->iov_offset = iov_offset; - s->total_size = 0; -} - -static inline bool -_iscsi_sgl_append(struct _iscsi_sgl *s, uint8_t *data, uint32_t data_len) -{ - if (s->iov_offset >= data_len) { - s->iov_offset -= data_len; - } else { - assert(s->iovcnt > 0); - s->iov->iov_base = data + s->iov_offset; - s->iov->iov_len = data_len - s->iov_offset; - s->total_size += data_len - s->iov_offset; - s->iov_offset = 0; - s->iov++; - s->iovcnt--; - if (s->iovcnt == 0) { - return false; - } - } - - return true; -} - /* Build iovec array to leave metadata space for every data block * when reading data segment from socket. */ static inline bool -_iscsi_sgl_append_with_md(struct _iscsi_sgl *s, +_iscsi_sgl_append_with_md(struct spdk_iov_sgl *s, void *buf, uint32_t buf_len, uint32_t data_len, struct spdk_dif_ctx *dif_ctx) { @@ -468,7 +432,7 @@ int iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt, struct spdk_iscsi_pdu *pdu, uint32_t *_mapped_length) { - struct _iscsi_sgl sgl; + struct spdk_iov_sgl sgl; int enable_digest; uint32_t total_ahs_len; uint32_t data_len; @@ -487,22 +451,22 @@ iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt, enable_digest = 0; } - _iscsi_sgl_init(&sgl, iovs, iovcnt, pdu->writev_offset); + spdk_iov_sgl_init(&sgl, iovs, iovcnt, pdu->writev_offset); /* BHS */ - if (!_iscsi_sgl_append(&sgl, (uint8_t *)&pdu->bhs, ISCSI_BHS_LEN)) { + if (!spdk_iov_sgl_append(&sgl, (uint8_t *)&pdu->bhs, ISCSI_BHS_LEN)) { goto end; } /* AHS */ if (total_ahs_len > 0) { - if (!_iscsi_sgl_append(&sgl, pdu->ahs, 4 * total_ahs_len)) { + if (!spdk_iov_sgl_append(&sgl, pdu->ahs, 4 * total_ahs_len)) { goto end; } } /* Header Digest */ if (enable_digest && conn->header_digest) { - if (!_iscsi_sgl_append(&sgl, pdu->header_digest, ISCSI_DIGEST_LEN)) { + if (!spdk_iov_sgl_append(&sgl, pdu->header_digest, ISCSI_DIGEST_LEN)) { goto end; } } @@ -510,7 +474,7 @@ iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt, /* Data Segment */ if (data_len > 0) { if (!pdu->dif_insert_or_strip) { - if (!_iscsi_sgl_append(&sgl, pdu->data, data_len)) { + if (!spdk_iov_sgl_append(&sgl, pdu->data, data_len)) { goto end; } } else { @@ -523,7 +487,7 @@ iscsi_build_iovs(struct spdk_iscsi_conn *conn, struct iovec *iovs, int iovcnt, /* Data Digest */ if (enable_digest && conn->data_digest && data_len != 0) { - _iscsi_sgl_append(&sgl, pdu->data_digest, ISCSI_DIGEST_LEN); + spdk_iov_sgl_append(&sgl, pdu->data_digest, ISCSI_DIGEST_LEN); } end: