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:
parent
17b2f5e931
commit
3612ab7a3c
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user