dif: Insert DIF into newly read data block by stream fashion
Add an new API spdk_dif_generate_stream() to insert DIF into the metadata space of newly read data block by stream fashion. This API is tested by replacing the previous DIF generation such that DIF is generated once all data was read. Change-Id: I757b4e6f10fe2d9d643f56ebb678c731cdad63bb Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446594 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Ziye Yang <ziye.yang@intel.com> Reviewed-by: wuzhouhui <wuzhouhui@kingsoft.com>
This commit is contained in:
parent
daf2206ec4
commit
466ca6d494
@ -285,4 +285,19 @@ int spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int num_iovs,
|
||||
uint32_t data_offset, uint32_t data_len,
|
||||
uint32_t *mapped_len,
|
||||
const struct spdk_dif_ctx *ctx);
|
||||
|
||||
/**
|
||||
* Generate and insert DIF into metadata space for newly read data block.
|
||||
*
|
||||
* \param buf Buffer to create extended LBA payload.
|
||||
* \param buf_len Length of the buffer to create extended LBA payload.
|
||||
* \param offset Offset to the newly read data.
|
||||
* \param read_len Length of the newly read data.
|
||||
* \param ctx DIF context.
|
||||
*
|
||||
* \return 0 on success and negated errno otherwise.
|
||||
*/
|
||||
int spdk_dif_generate_stream(uint8_t *buf, uint32_t buf_len,
|
||||
uint32_t offset, uint32_t read_len,
|
||||
const struct spdk_dif_ctx *ctx);
|
||||
#endif /* SPDK_DIF_H */
|
||||
|
@ -1370,3 +1370,42 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int num_iovs,
|
||||
|
||||
return iovcnt;
|
||||
}
|
||||
|
||||
int
|
||||
spdk_dif_generate_stream(uint8_t *buf, uint32_t buf_len,
|
||||
uint32_t offset, uint32_t read_len,
|
||||
const struct spdk_dif_ctx *ctx)
|
||||
{
|
||||
uint32_t data_block_size, offset_blocks, num_blocks, i;
|
||||
uint16_t guard = 0;
|
||||
|
||||
if (buf == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (offset + num_blocks * ctx->block_size > buf_len) {
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
buf += offset;
|
||||
|
||||
for (i = 0; i < num_blocks; i++) {
|
||||
if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
|
||||
guard = spdk_crc16_t10dif(ctx->guard_seed, buf, ctx->guard_interval);
|
||||
}
|
||||
|
||||
_dif_generate(buf + ctx->guard_interval, guard, offset_blocks + i, ctx);
|
||||
|
||||
buf += ctx->block_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1420,6 +1420,9 @@ set_md_interleave_iovs_test(void)
|
||||
read_base = ut_readv(0, 1024, dif_iovs, 4);
|
||||
CU_ASSERT(read_base == 1024);
|
||||
|
||||
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,
|
||||
read_base, 4096 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 4);
|
||||
@ -1432,6 +1435,9 @@ set_md_interleave_iovs_test(void)
|
||||
read_base += ut_readv(read_base, 3071, dif_iovs, 4);
|
||||
CU_ASSERT(read_base == 4095);
|
||||
|
||||
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,
|
||||
read_base, 4096 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 4);
|
||||
@ -1444,6 +1450,9 @@ set_md_interleave_iovs_test(void)
|
||||
read_base += ut_readv(read_base, 1 + 4096 * 2 + 512, dif_iovs, 4);
|
||||
CU_ASSERT(read_base == 4096 * 3 + 512);
|
||||
|
||||
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,
|
||||
read_base, 4096 * 4, &mapped_len, &ctx);
|
||||
CU_ASSERT(rc == 1);
|
||||
@ -1453,7 +1462,7 @@ set_md_interleave_iovs_test(void)
|
||||
read_base += ut_readv(read_base, 3584, dif_iovs, 1);
|
||||
CU_ASSERT(read_base == 4096 * 4);
|
||||
|
||||
rc = spdk_dif_generate(&iov1, 1, 4, &ctx);
|
||||
rc = spdk_dif_generate_stream(buf1, (4096 + 128) * 4, 4096 * 3 + 512, 3584, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
/* The second data buffer:
|
||||
@ -1482,6 +1491,57 @@ set_md_interleave_iovs_test(void)
|
||||
free(buf2);
|
||||
}
|
||||
|
||||
static void
|
||||
dif_generate_stream_test(void)
|
||||
{
|
||||
struct iovec iov;
|
||||
struct spdk_dif_ctx ctx;
|
||||
struct spdk_dif_error err_blk;
|
||||
uint32_t dif_flags;
|
||||
int rc;
|
||||
|
||||
_iov_alloc_buf(&iov, (512 + 8) * 5);
|
||||
|
||||
rc = ut_data_pattern_generate(&iov, 1, 512, 8, 5);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
|
||||
SPDK_DIF_FLAGS_REFTAG_CHECK;
|
||||
|
||||
rc = spdk_dif_ctx_init(&ctx, 512, 8, true, false, SPDK_DIF_TYPE1, dif_flags,
|
||||
22, 0xFFFF, 0x22, GUARD_SEED);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 0, 511, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 511, 1, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 512, 256, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 768, 512, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 1280, 1024, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 2304, 256, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_stream(iov.iov_base, (512 + 8) * 5, 2560, 512, &ctx);
|
||||
CU_ASSERT(rc == -ERANGE);
|
||||
|
||||
rc = spdk_dif_verify(&iov, 1, 5, &ctx, &err_blk);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = ut_data_pattern_verify(&iov, 1, 512, 8, 5);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
_iov_free_buf(&iov);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -1566,7 +1626,8 @@ main(int argc, char **argv)
|
||||
dix_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test) == NULL ||
|
||||
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_test", set_md_interleave_iovs_test) == NULL ||
|
||||
CU_add_test(suite, "dif_generate_stream_test", dif_generate_stream_test) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
Loading…
Reference in New Issue
Block a user