dif: Add spdk_dif_update_crc32c_stream to update CRC32C by stream fashion
Add spdk_dif_update_crc32c_stream to update CRC32C by stream fashion. spdk_dif_update_crc32c_stream utilizes the updated _dif_update_crc32c_split. A minor bug was found in UT for spdk_dif_update_crc32c and is fixed together in this patch. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: I92358e845e8e2e17c6f288aa718b947e71e6e1fb Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458919 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
4c2e52b935
commit
767c046e77
@ -366,4 +366,20 @@ int spdk_dif_verify_stream(struct iovec *iovs, int iovcnt,
|
|||||||
uint32_t data_offset, uint32_t data_len,
|
uint32_t data_offset, uint32_t data_len,
|
||||||
struct spdk_dif_ctx *ctx,
|
struct spdk_dif_ctx *ctx,
|
||||||
struct spdk_dif_error *err_blk);
|
struct spdk_dif_error *err_blk);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate CRC-32C checksum of the specified range in the extended LBA payload.
|
||||||
|
*
|
||||||
|
* \param iovs iovec array describing the extended LBA payload.
|
||||||
|
* \param iovcnt Number of elements in the iovec array.
|
||||||
|
* \param data_offset Offset to the range
|
||||||
|
* \param data_len Length of the range
|
||||||
|
* \param crc32c Initial and updated CRC-32C value.
|
||||||
|
* \param ctx DIF context.
|
||||||
|
*
|
||||||
|
* \return 0 on success and negated errno otherwise.
|
||||||
|
*/
|
||||||
|
int spdk_dif_update_crc32c_stream(struct iovec *iovs, int iovcnt,
|
||||||
|
uint32_t data_offset, uint32_t data_len,
|
||||||
|
uint32_t *crc32c, const struct spdk_dif_ctx *ctx);
|
||||||
#endif /* SPDK_DIF_H */
|
#endif /* SPDK_DIF_H */
|
||||||
|
@ -1644,3 +1644,40 @@ spdk_dif_verify_stream(struct iovec *iovs, int iovcnt,
|
|||||||
error:
|
error:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
spdk_dif_update_crc32c_stream(struct iovec *iovs, int iovcnt,
|
||||||
|
uint32_t data_offset, uint32_t data_len,
|
||||||
|
uint32_t *_crc32c, const struct spdk_dif_ctx *ctx)
|
||||||
|
{
|
||||||
|
uint32_t buf_len = 0, buf_offset = 0, len, offset_in_block;
|
||||||
|
uint32_t crc32c;
|
||||||
|
struct _dif_sgl sgl;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if (iovs == NULL || iovcnt == 0) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc32c = *_crc32c;
|
||||||
|
_dif_sgl_init(&sgl, iovs, iovcnt);
|
||||||
|
|
||||||
|
rc = _dif_sgl_setup_stream(&sgl, &buf_offset, &buf_len, data_offset, data_len, ctx);
|
||||||
|
if (rc != 0) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (buf_len != 0) {
|
||||||
|
len = spdk_min(buf_len, _to_next_boundary(buf_offset, ctx->block_size));
|
||||||
|
offset_in_block = buf_offset % ctx->block_size;
|
||||||
|
|
||||||
|
crc32c = _dif_update_crc32c_split(&sgl, offset_in_block, len, crc32c, ctx);
|
||||||
|
|
||||||
|
buf_len -= len;
|
||||||
|
buf_offset += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
*_crc32c = crc32c;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -2171,7 +2171,7 @@ update_crc32c_test(void)
|
|||||||
_iov_alloc_buf(&iovs[3], 3 + 123);
|
_iov_alloc_buf(&iovs[3], 3 + 123);
|
||||||
|
|
||||||
/* data[1][511:123], md[1][5:0] */
|
/* data[1][511:123], md[1][5:0] */
|
||||||
_iov_alloc_buf(&iovs[4], 399 + 6);
|
_iov_alloc_buf(&iovs[4], 389 + 6);
|
||||||
|
|
||||||
/* md[1][7:6], data[2][511:0], md[2][7:0], data[3][431:0] */
|
/* md[1][7:6], data[2][511:0], md[2][7:0], data[3][431:0] */
|
||||||
_iov_alloc_buf(&iovs[5], 2 + 512 + 8 + 432);
|
_iov_alloc_buf(&iovs[5], 2 + 512 + 8 + 432);
|
||||||
@ -2281,6 +2281,68 @@ _dif_update_crc32c_split_test(void)
|
|||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dif_update_crc32c_stream_multi_segments_test(void)
|
||||||
|
{
|
||||||
|
struct spdk_dif_ctx ctx = {};
|
||||||
|
struct iovec iov = {};
|
||||||
|
uint8_t *buf;
|
||||||
|
uint32_t dif_flags, crc32c1, crc32c2;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK |
|
||||||
|
SPDK_DIF_FLAGS_REFTAG_CHECK;
|
||||||
|
|
||||||
|
rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1,
|
||||||
|
dif_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
buf = calloc(1, (4096 + 128) * 4);
|
||||||
|
SPDK_CU_ASSERT_FATAL(buf != NULL);
|
||||||
|
_iov_set_buf(&iov, buf, (4096 + 128) * 4);
|
||||||
|
|
||||||
|
rc = ut_data_pattern_generate(&iov, 1, 4096 + 128, 128, 4);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
rc = spdk_dif_generate(&iov, 1, 4, &ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
crc32c1 = UT_CRC32C_XOR;
|
||||||
|
crc32c2 = UT_CRC32C_XOR;
|
||||||
|
|
||||||
|
/* 1st data segment */
|
||||||
|
_iov_set_buf(&iov, buf, 1024);
|
||||||
|
spdk_dif_ctx_set_data_offset(&ctx, 0);
|
||||||
|
|
||||||
|
rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 1024, &crc32c1, &ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
/* 2nd data segment */
|
||||||
|
_iov_set_buf(&iov, buf + 1024, (3072 + 128) + (4096 + 128) * 2 + 512);
|
||||||
|
spdk_dif_ctx_set_data_offset(&ctx, 1024);
|
||||||
|
|
||||||
|
rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3072 + 4096 * 2 + 512, &crc32c1, &ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
/* 3rd data segment */
|
||||||
|
_iov_set_buf(&iov, buf + (4096 + 128) * 3 + 512, 3584 + 128);
|
||||||
|
spdk_dif_ctx_set_data_offset(&ctx, 4096 * 3);
|
||||||
|
|
||||||
|
rc = spdk_dif_update_crc32c_stream(&iov, 1, 0, 3584, &crc32c1, &ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
/* Update CRC32C for all data segments once */
|
||||||
|
_iov_set_buf(&iov, buf, (4096 + 128) * 4);
|
||||||
|
spdk_dif_ctx_set_data_offset(&ctx, 0);
|
||||||
|
|
||||||
|
rc = spdk_dif_update_crc32c(&iov, 1, 4, &crc32c2, &ctx);
|
||||||
|
CU_ASSERT(rc == 0);
|
||||||
|
|
||||||
|
CU_ASSERT(crc32c1 == crc32c2);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -2379,7 +2441,9 @@ main(int argc, char **argv)
|
|||||||
dif_verify_stream_multi_segments_test) == NULL ||
|
dif_verify_stream_multi_segments_test) == NULL ||
|
||||||
CU_add_test(suite, "update_crc32c_test", update_crc32c_test) == NULL ||
|
CU_add_test(suite, "update_crc32c_test", update_crc32c_test) == NULL ||
|
||||||
CU_add_test(suite, "_dif_update_crc32c_split_test",
|
CU_add_test(suite, "_dif_update_crc32c_split_test",
|
||||||
_dif_update_crc32c_split_test) == NULL
|
_dif_update_crc32c_split_test) == NULL ||
|
||||||
|
CU_add_test(suite, "dif_update_crc32c_stream_multi_segments_test",
|
||||||
|
dif_update_crc32c_stream_multi_segments_test) == NULL
|
||||||
) {
|
) {
|
||||||
CU_cleanup_registry();
|
CU_cleanup_registry();
|
||||||
return CU_get_error();
|
return CU_get_error();
|
||||||
|
Loading…
Reference in New Issue
Block a user