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: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453756
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-09 10:22:55 +09:00 committed by Jim Harris
parent 17b2f5e931
commit 3612ab7a3c
2 changed files with 76 additions and 2 deletions

View File

@ -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);
}
}

View File

@ -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]);
}
}