dif: Support a single iovec for data buffer in spdk_dif_set_md_interleave_iovs

Currently iSCSI target have used a single contiguous data buffer
both for read and write I/O. Hence spdk_dif_set_md_interleave_iovs
accepts a single contiguous data buffer and its size as arguments.

On the other hand, NVMe-TCP target recently has changed to use
SGL data buffer instead.

DIF strip and insert will be supported in NVMe-TCP target next,
and updating spdk_dif_set_md_interleave_iovs to accept SGL data
buffer will be helpful.

This patch changes the interface of spdk_dif_set_md_interleave_iovs,
but allows only a single iovec. The next patch will allow multiple
iovecs.

Change-Id: I31b09814f8ec920e463a5b1be8fb88cad7d277fb
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453735
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Shuhei Matsumoto 2019-05-15 10:22:01 +09:00 committed by Jim Harris
parent 5027579f67
commit 2821762a60
4 changed files with 55 additions and 31 deletions

View File

@ -269,8 +269,8 @@ int spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
* *
* \param iovs iovec array set by this function. * \param iovs iovec array set by this function.
* \param iovcnt 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_iovs SGL for the buffer to create extended LBA payload.
* \param buf_len Length of the buffer to create extended LBA payload. * \param buf_iovcnt Size of the SGL for the buffer to create extended LBA payload.
* \param data_offset Offset to store the next incoming data. * \param data_offset Offset to store the next incoming data.
* \param data_len Expected data length of the payload. * \param data_len Expected data length of the payload.
* \param mapped_len Output parameter that will contain data length mapped by * \param mapped_len Output parameter that will contain data length mapped by
@ -281,7 +281,7 @@ int spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
* errno otherwise. * errno otherwise.
*/ */
int spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt, int spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
uint8_t *buf, uint32_t buf_len, struct iovec *buf_iovs, int buf_iovcnt,
uint32_t data_offset, uint32_t data_len, uint32_t data_offset, uint32_t data_len,
uint32_t *mapped_len, uint32_t *mapped_len,
const struct spdk_dif_ctx *ctx); const struct spdk_dif_ctx *ctx);

View File

@ -367,7 +367,7 @@ iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn,
uint32_t segment_len) uint32_t segment_len)
{ {
struct spdk_dif_ctx dif_ctx; struct spdk_dif_ctx dif_ctx;
struct iovec iovs[32]; struct iovec buf_iov, iovs[32];
int rc, _rc; int rc, _rc;
if (spdk_likely(!spdk_iscsi_get_dif_ctx(conn, pdu, &dif_ctx))) { if (spdk_likely(!spdk_iscsi_get_dif_ctx(conn, pdu, &dif_ctx))) {
@ -376,8 +376,9 @@ iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn,
pdu->data_buf + pdu->data_valid_bytes); pdu->data_buf + pdu->data_valid_bytes);
} else { } else {
pdu->dif_insert_or_strip = true; pdu->dif_insert_or_strip = true;
rc = spdk_dif_set_md_interleave_iovs(iovs, 32, buf_iov.iov_base = pdu->data_buf;
pdu->data_buf, pdu->data_buf_len, buf_iov.iov_len = pdu->data_buf_len;
rc = spdk_dif_set_md_interleave_iovs(iovs, 32, &buf_iov, 1,
pdu->data_valid_bytes, segment_len, NULL, pdu->data_valid_bytes, segment_len, NULL,
&dif_ctx); &dif_ctx);
if (rc > 0) { if (rc > 0) {
@ -637,12 +638,15 @@ _iov_ctx_set_md_interleave_iov(struct _iov_ctx *ctx,
{ {
int rc; int rc;
uint32_t mapped_len = 0; uint32_t mapped_len = 0;
struct iovec buf_iov;
if (ctx->iov_offset >= data_len) { if (ctx->iov_offset >= data_len) {
ctx->iov_offset -= buf_len; ctx->iov_offset -= buf_len;
} else { } else {
buf_iov.iov_base = buf;
buf_iov.iov_len = buf_len;
rc = spdk_dif_set_md_interleave_iovs(ctx->iov, ctx->num_iovs - ctx->iovcnt, rc = spdk_dif_set_md_interleave_iovs(ctx->iov, ctx->num_iovs - ctx->iovcnt,
buf, buf_len, &buf_iov, 1,
ctx->iov_offset, data_len, &mapped_len, ctx->iov_offset, data_len, &mapped_len,
dif_ctx); dif_ctx);
if (rc < 0) { if (rc < 0) {

View File

@ -1285,8 +1285,8 @@ spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
return 0; return 0;
} }
int static int
spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt, dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
uint8_t *buf, uint32_t buf_len, uint8_t *buf, uint32_t buf_len,
uint32_t data_offset, uint32_t data_len, uint32_t data_offset, uint32_t data_len,
uint32_t *_mapped_len, uint32_t *_mapped_len,
@ -1296,22 +1296,8 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
uint32_t num_blocks, offset_blocks; uint32_t num_blocks, offset_blocks;
struct _dif_sgl sgl; struct _dif_sgl sgl;
if (iovs == NULL || iovcnt == 0) {
return -EINVAL;
}
data_block_size = ctx->block_size - ctx->md_size; data_block_size = ctx->block_size - ctx->md_size;
if ((data_len % data_block_size) != 0) {
SPDK_ERRLOG("Data length must be a multiple of data block size\n");
return -EINVAL;
}
if (data_offset >= data_len) {
SPDK_ERRLOG("Data offset must be smaller than data length\n");
return -ERANGE;
}
num_blocks = data_len / data_block_size; num_blocks = data_len / data_block_size;
if (buf_len < num_blocks * ctx->block_size) { if (buf_len < num_blocks * ctx->block_size) {
@ -1347,6 +1333,40 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
return iovcnt - sgl.iovcnt; return iovcnt - sgl.iovcnt;
} }
int
spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
struct iovec *buf_iovs, int buf_iovcnt,
uint32_t data_offset, uint32_t data_len,
uint32_t *_mapped_len,
const struct spdk_dif_ctx *ctx)
{
uint32_t data_block_size;
if (iovs == NULL || iovcnt == 0 || buf_iovs == NULL || buf_iovcnt == 0) {
return -EINVAL;
}
data_block_size = ctx->block_size - ctx->md_size;
if ((data_len % data_block_size) != 0) {
SPDK_ERRLOG("Data length must be a multiple of data block size\n");
return -EINVAL;
}
if (data_offset >= data_len) {
SPDK_ERRLOG("Data offset must be smaller than data length\n");
return -ERANGE;
}
if (buf_iovcnt == 1) {
return dif_set_md_interleave_iovs(iovs, iovcnt,
buf_iovs[0].iov_base, buf_iovs[0].iov_len,
data_offset, data_len, _mapped_len, ctx);
} else {
return -EINVAL;
}
}
int int
spdk_dif_generate_stream(uint8_t *buf, uint32_t buf_len, spdk_dif_generate_stream(uint8_t *buf, uint32_t buf_len,
uint32_t offset, uint32_t read_len, uint32_t offset, uint32_t read_len,

View File

@ -1410,7 +1410,7 @@ set_md_interleave_iovs_test(void)
SPDK_CU_ASSERT_FATAL(buf1 != NULL); SPDK_CU_ASSERT_FATAL(buf1 != NULL);
_iov_set_buf(&iov1, buf1, (4096 + 128) * 4); _iov_set_buf(&iov1, buf1, (4096 + 128) * 4);
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, buf1, (4096 + 128) * 4, rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
0, 4096 * 4, &mapped_len, &ctx); 0, 4096 * 4, &mapped_len, &ctx);
CU_ASSERT(rc == 4); CU_ASSERT(rc == 4);
CU_ASSERT(mapped_len == 4096 * 4); CU_ASSERT(mapped_len == 4096 * 4);
@ -1425,7 +1425,7 @@ set_md_interleave_iovs_test(void)
rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 0, 1024, &ctx); rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 0, 1024, &ctx);
CU_ASSERT(rc == 0); CU_ASSERT(rc == 0);
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, buf1, (4096 + 128) * 4, rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
read_base, 4096 * 4, &mapped_len, &ctx); read_base, 4096 * 4, &mapped_len, &ctx);
CU_ASSERT(rc == 4); CU_ASSERT(rc == 4);
CU_ASSERT(mapped_len == 3072 + 4096 * 3); CU_ASSERT(mapped_len == 3072 + 4096 * 3);
@ -1440,7 +1440,7 @@ set_md_interleave_iovs_test(void)
rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 1024, 3071, &ctx); rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 1024, 3071, &ctx);
CU_ASSERT(rc == 0); CU_ASSERT(rc == 0);
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, buf1, (4096 + 128) * 4, rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
read_base, 4096 * 4, &mapped_len, &ctx); read_base, 4096 * 4, &mapped_len, &ctx);
CU_ASSERT(rc == 4); CU_ASSERT(rc == 4);
CU_ASSERT(mapped_len == 1 + 4096 * 3); CU_ASSERT(mapped_len == 1 + 4096 * 3);
@ -1455,7 +1455,7 @@ set_md_interleave_iovs_test(void)
rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 4095, 1 + 4096 * 2 + 512, &ctx); rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 4095, 1 + 4096 * 2 + 512, &ctx);
CU_ASSERT(rc == 0); CU_ASSERT(rc == 0);
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, buf1, (4096 + 128) * 4, rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 4, &iov1, 1,
read_base, 4096 * 4, &mapped_len, &ctx); read_base, 4096 * 4, &mapped_len, &ctx);
CU_ASSERT(rc == 1); CU_ASSERT(rc == 1);
CU_ASSERT(mapped_len == 3584); CU_ASSERT(mapped_len == 3584);