Commit 3612ab7a authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

dif: Support multiple iovecs for data buffer in spdk_dif_generate_stream



This patch allows multiple iovecs as argument in spdk_dif_generate_stream.

Subsequent patches will support DIF strip and insert in SPDK NVMe-TCP
target based on the patch series.

Change-Id: I1f3d6c5b9f924bb52525e1611db403846d087563
Signed-off-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453756


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 17b2f5e9
Loading
Loading
Loading
Loading
+32 −1
Original line number Diff line number Diff line
@@ -1461,6 +1461,37 @@ dif_generate_stream(uint8_t *buf, uint32_t buf_len,
	return 0;
}

static int
dif_generate_stream_split(struct iovec *iovs, int iovcnt,
			  uint32_t offset, uint32_t read_len,
			  const struct spdk_dif_ctx *ctx)
{
	uint32_t data_block_size, offset_blocks, num_blocks, i;
	struct _dif_sgl sgl;

	data_block_size = ctx->block_size - ctx->md_size;

	offset_blocks = offset / data_block_size;
	read_len += offset % data_block_size;

	offset = offset_blocks * ctx->block_size;
	num_blocks = read_len / data_block_size;

	_dif_sgl_init(&sgl, iovs, iovcnt);

	if (!_dif_sgl_is_valid(&sgl, offset + num_blocks * ctx->block_size)) {
		return -ERANGE;
	}

	_dif_sgl_fast_forward(&sgl, offset);

	for (i = 0; i < num_blocks; i++) {
		_dif_generate_split(&sgl, offset_blocks + i, ctx);
	}

	return 0;
}

int
spdk_dif_generate_stream(struct iovec *iovs, int iovcnt,
			 uint32_t offset, uint32_t read_len,
@@ -1474,6 +1505,6 @@ spdk_dif_generate_stream(struct iovec *iovs, int iovcnt,
		return dif_generate_stream(iovs[0].iov_base, iovs[0].iov_len,
					   offset, read_len, ctx);
	} else {
		return -EINVAL;
		return dif_generate_stream_split(iovs, iovcnt, offset, read_len, ctx);
	}
}
+44 −1
Original line number Diff line number Diff line
@@ -1497,7 +1497,8 @@ static void
set_md_interleave_iovs_split_test(void)
{
	struct spdk_dif_ctx ctx = {};
	struct iovec iovs1[7], dif_iovs[8];
	struct spdk_dif_error err_blk = {};
	struct iovec iovs1[7], iovs2[7], dif_iovs[8];
	uint32_t dif_check_flags, mapped_len = 0, read_base = 0;
	int rc, i;

@@ -1536,6 +1537,9 @@ set_md_interleave_iovs_split_test(void)
	read_base = ut_readv(0, 128, dif_iovs, 8);
	CU_ASSERT(read_base == 128);

	rc = spdk_dif_generate_stream(iovs1, 7, 0, 128, &ctx);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
					     read_base, 512 * 4, &mapped_len, &ctx);
	CU_ASSERT(rc == 8);
@@ -1552,6 +1556,9 @@ set_md_interleave_iovs_split_test(void)
	read_base += ut_readv(read_base, 383, dif_iovs, 8);
	CU_ASSERT(read_base == 511);

	rc = spdk_dif_generate_stream(iovs1, 7, 128, 383, &ctx);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
					     read_base, 512 * 4, &mapped_len, &ctx);
	CU_ASSERT(rc == 8);
@@ -1568,6 +1575,9 @@ set_md_interleave_iovs_split_test(void)
	read_base += ut_readv(read_base, 1 + 512 * 2 + 128, dif_iovs, 8);
	CU_ASSERT(read_base == 512 * 3 + 128);

	rc = spdk_dif_generate_stream(iovs1, 7, 383, 1 + 512 * 2 + 128, &ctx);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
					     read_base, 512 * 4, &mapped_len, &ctx);
	CU_ASSERT(rc == 2);
@@ -1578,8 +1588,41 @@ set_md_interleave_iovs_split_test(void)
	read_base += ut_readv(read_base, 384, dif_iovs, 8);
	CU_ASSERT(read_base == 512 * 4);

	rc = spdk_dif_generate_stream(iovs1, 7, 512 * 3 + 128, 384, &ctx);
	CU_ASSERT(rc == 0);

	/* The second SGL data buffer:
	 * - Set data pattern with a space for metadata for each block.
	 */
	_iov_alloc_buf(&iovs2[0], 512 + 8 + 128);
	_iov_alloc_buf(&iovs2[1], 128);
	_iov_alloc_buf(&iovs2[2], 256 + 8);
	_iov_alloc_buf(&iovs2[3], 100);
	_iov_alloc_buf(&iovs2[4], 412 + 5);
	_iov_alloc_buf(&iovs2[5], 3 + 300);
	_iov_alloc_buf(&iovs2[6], 212 + 8);

	rc = ut_data_pattern_generate(iovs2, 7, 512 + 8, 8, 4);
	CU_ASSERT(rc == 0);
	rc = spdk_dif_generate(iovs2, 7, 4, &ctx);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_verify(iovs1, 7, 4, &ctx, &err_blk);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_verify(iovs2, 7, 4, &ctx, &err_blk);
	CU_ASSERT(rc == 0);

	/* Compare the first and the second SGL data buffer by byte. */
	for (i = 0; i < 7; i++) {
		rc = memcmp(iovs1[i].iov_base, iovs2[i].iov_base,
			    iovs1[i].iov_len);
		CU_ASSERT(rc == 0);
	}

	for (i = 0; i < 7; i++) {
		_iov_free_buf(&iovs1[i]);
		_iov_free_buf(&iovs2[i]);
	}
}