Commit 2821762a authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

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: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453735


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent 5027579f
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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 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 buf_iovs SGL for 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_len Expected data length of the payload.
 * \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.
 */
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 *mapped_len,
				    const struct spdk_dif_ctx *ctx);
+8 −4
Original line number Diff line number Diff line
@@ -367,7 +367,7 @@ iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn,
			     uint32_t segment_len)
{
	struct spdk_dif_ctx dif_ctx;
	struct iovec iovs[32];
	struct iovec buf_iov, iovs[32];
	int rc, _rc;

	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);
	} else {
		pdu->dif_insert_or_strip = true;
		rc = spdk_dif_set_md_interleave_iovs(iovs, 32,
						     pdu->data_buf, pdu->data_buf_len,
		buf_iov.iov_base = pdu->data_buf;
		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,
						     &dif_ctx);
		if (rc > 0) {
@@ -637,12 +638,15 @@ _iov_ctx_set_md_interleave_iov(struct _iov_ctx *ctx,
{
	int rc;
	uint32_t mapped_len = 0;
	struct iovec buf_iov;

	if (ctx->iov_offset >= data_len) {
		ctx->iov_offset -= buf_len;
	} 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,
						     buf, buf_len,
						     &buf_iov, 1,
						     ctx->iov_offset, data_len, &mapped_len,
						     dif_ctx);
		if (rc < 0) {
+40 −20
Original line number Diff line number Diff line
@@ -1285,8 +1285,8 @@ spdk_dix_inject_error(struct iovec *iovs, int iovcnt, struct iovec *md_iov,
	return 0;
}

int
spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
static int
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,
@@ -1296,22 +1296,8 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
	uint32_t num_blocks, offset_blocks;
	struct _dif_sgl sgl;

	if (iovs == NULL || 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;
	}

	num_blocks = data_len / data_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;
}

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
spdk_dif_generate_stream(uint8_t *buf, uint32_t buf_len,
			 uint32_t offset, uint32_t read_len,
+4 −4
Original line number Diff line number Diff line
@@ -1410,7 +1410,7 @@ set_md_interleave_iovs_test(void)
	SPDK_CU_ASSERT_FATAL(buf1 != NULL);
	_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);
	CU_ASSERT(rc == 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);
	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);
	CU_ASSERT(rc == 4);
	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);
	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);
	CU_ASSERT(rc == 4);
	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);
	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);
	CU_ASSERT(rc == 1);
	CU_ASSERT(mapped_len == 3584);