dif: Support multiple iovecs for data buffer in spdk_dif_set_md_interleave_iovs
This patch allows multiple iovecs as argument of spdk_dif_set_md_interleave_iovs. Subsequent patches will support SGL data buffer in spdk_dif_generate_stream too. UT code tests only spdk_dif_set_md_interleave until then. Change-Id: I7ac03a3c8f7bcd922af4f29b404ebf3acc4b89e5 Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/453736 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
2821762a60
commit
079ad446d2
@ -1333,6 +1333,64 @@ dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
|
||||
return iovcnt - sgl.iovcnt;
|
||||
}
|
||||
|
||||
static int
|
||||
dif_set_md_interleave_iovs_split(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, head_unalign;
|
||||
uint32_t num_blocks, offset_blocks;
|
||||
struct _dif_sgl dif_sgl;
|
||||
struct _dif_sgl buf_sgl;
|
||||
uint8_t *buf;
|
||||
uint32_t buf_len, remaining;
|
||||
|
||||
data_block_size = ctx->block_size - ctx->md_size;
|
||||
num_blocks = data_len / data_block_size;
|
||||
|
||||
_dif_sgl_init(&dif_sgl, iovs, iovcnt);
|
||||
_dif_sgl_init(&buf_sgl, buf_iovs, buf_iovcnt);
|
||||
|
||||
if (!_dif_sgl_is_valid(&buf_sgl, num_blocks * ctx->block_size)) {
|
||||
SPDK_ERRLOG("Buffer overflow will occur.\n");
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
offset_blocks = data_offset / data_block_size;
|
||||
head_unalign = data_offset % data_block_size;
|
||||
|
||||
_dif_sgl_fast_forward(&buf_sgl, offset_blocks * ctx->block_size);
|
||||
|
||||
while (offset_blocks < num_blocks) {
|
||||
_dif_sgl_fast_forward(&buf_sgl, head_unalign);
|
||||
|
||||
remaining = data_block_size - head_unalign;
|
||||
while (remaining != 0) {
|
||||
_dif_sgl_get_buf(&buf_sgl, (void *)&buf, &buf_len);
|
||||
buf_len = spdk_min(buf_len, remaining);
|
||||
|
||||
if (!_dif_sgl_append(&dif_sgl, buf, buf_len)) {
|
||||
goto end;
|
||||
}
|
||||
_dif_sgl_advance(&buf_sgl, buf_len);
|
||||
remaining -= buf_len;
|
||||
}
|
||||
_dif_sgl_fast_forward(&buf_sgl, ctx->md_size);
|
||||
offset_blocks++;
|
||||
|
||||
head_unalign = 0;
|
||||
}
|
||||
|
||||
end:
|
||||
if (_mapped_len != NULL) {
|
||||
*_mapped_len = dif_sgl.total_size;
|
||||
}
|
||||
|
||||
return iovcnt - dif_sgl.iovcnt;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
|
||||
struct iovec *buf_iovs, int buf_iovcnt,
|
||||
@ -1363,7 +1421,8 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt,
|
||||
buf_iovs[0].iov_base, buf_iovs[0].iov_len,
|
||||
data_offset, data_len, _mapped_len, ctx);
|
||||
} else {
|
||||
return -EINVAL;
|
||||
return dif_set_md_interleave_iovs_split(iovs, iovcnt, buf_iovs, buf_iovcnt,
|
||||
data_offset, data_len, _mapped_len, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1493,6 +1493,96 @@ set_md_interleave_iovs_test(void)
|
||||
free(buf2);
|
||||
}
|
||||
|
||||
static void
|
||||
set_md_interleave_iovs_split_test(void)
|
||||
{
|
||||
struct spdk_dif_ctx ctx = {};
|
||||
struct iovec iovs1[7], dif_iovs[8];
|
||||
uint32_t dif_check_flags, mapped_len = 0, read_base = 0;
|
||||
int rc, i;
|
||||
|
||||
dif_check_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
|
||||
SPDK_DIF_FLAGS_REFTAG_CHECK;
|
||||
|
||||
rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1,
|
||||
dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
/* The first SGL data buffer:
|
||||
* - Create iovec array to leave a space for metadata for each block
|
||||
* - Split vectored read and so creating iovec array is done before every vectored read.
|
||||
*/
|
||||
_iov_alloc_buf(&iovs1[0], 512 + 8 + 128);
|
||||
_iov_alloc_buf(&iovs1[1], 128);
|
||||
_iov_alloc_buf(&iovs1[2], 256 + 8);
|
||||
_iov_alloc_buf(&iovs1[3], 100);
|
||||
_iov_alloc_buf(&iovs1[4], 412 + 5);
|
||||
_iov_alloc_buf(&iovs1[5], 3 + 300);
|
||||
_iov_alloc_buf(&iovs1[6], 212 + 8);
|
||||
|
||||
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
|
||||
0, 512 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 8);
|
||||
CU_ASSERT(mapped_len == 512 * 4);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base, 512) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
|
||||
|
||||
read_base = ut_readv(0, 128, dif_iovs, 8);
|
||||
CU_ASSERT(read_base == 128);
|
||||
|
||||
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
|
||||
read_base, 512 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 8);
|
||||
CU_ASSERT(mapped_len == 384 + 512 * 3);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 128, 384) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
|
||||
|
||||
read_base += ut_readv(read_base, 383, dif_iovs, 8);
|
||||
CU_ASSERT(read_base == 511);
|
||||
|
||||
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
|
||||
read_base, 512 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 8);
|
||||
CU_ASSERT(mapped_len == 1 + 512 * 3);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[0].iov_base + 511, 1) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[0].iov_base + 512 + 8, 128) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[2], iovs1[1].iov_base, 128) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[3], iovs1[2].iov_base, 256) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[4], iovs1[3].iov_base, 100) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[5], iovs1[4].iov_base, 412) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[6], iovs1[5].iov_base + 3, 300) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[7], iovs1[6].iov_base, 212) == true);
|
||||
|
||||
read_base += ut_readv(read_base, 1 + 512 * 2 + 128, dif_iovs, 8);
|
||||
CU_ASSERT(read_base == 512 * 3 + 128);
|
||||
|
||||
rc = spdk_dif_set_md_interleave_iovs(dif_iovs, 8, iovs1, 7,
|
||||
read_base, 512 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 2);
|
||||
CU_ASSERT(mapped_len == 384);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[0], iovs1[5].iov_base + 3 + 128, 172) == true);
|
||||
CU_ASSERT(_iov_check(&dif_iovs[1], iovs1[6].iov_base, 212) == true);
|
||||
|
||||
read_base += ut_readv(read_base, 384, dif_iovs, 8);
|
||||
CU_ASSERT(read_base == 512 * 4);
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
_iov_free_buf(&iovs1[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dif_generate_stream_test(void)
|
||||
{
|
||||
@ -1629,6 +1719,8 @@ main(int argc, char **argv)
|
||||
CU_add_test(suite, "dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test",
|
||||
dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test) == NULL ||
|
||||
CU_add_test(suite, "set_md_interleave_iovs_test", set_md_interleave_iovs_test) == NULL ||
|
||||
CU_add_test(suite, "set_md_interleave_iovs_split_test",
|
||||
set_md_interleave_iovs_split_test) == NULL ||
|
||||
CU_add_test(suite, "dif_generate_stream_test", dif_generate_stream_test) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
|
Loading…
Reference in New Issue
Block a user