dif: Return DIF error information at verification for copied extended LBA payload.
For copied extended LBA payload, Introduce a struct to collect DIF error information and pass the reference to the struct to bit-flip error injection and verification. This change will make logging of DIF error and comparison between injection and verification possible for copied extended LBA payload. Merging this patch to the previous is possible but add this as a separate patch to reduce the patch size. Change-Id: I9f7ac1332fe63cb206c692d0876c8de41ef9286f Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/435227 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: wuzhouhui <wuzhouhui@kingsoft.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
bc5507e440
commit
045e77c235
@ -172,11 +172,13 @@ int spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_
|
||||
* \param bounce_iov A contiguous buffer forming extended LBA payload.
|
||||
* \param num_blocks Number of blocks of the LBA payload.
|
||||
* \param ctx DIF context.
|
||||
* \param err_blk Error information of the block in which DIF error is found.
|
||||
*
|
||||
* \return 0 on success and negated errno otherwise.
|
||||
*/
|
||||
int spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx);
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
|
||||
struct spdk_dif_error *err_blk);
|
||||
|
||||
/**
|
||||
* Inject bit flip error to extended LBA payload.
|
||||
|
@ -705,7 +705,8 @@ spdk_dif_generate_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
|
||||
static int
|
||||
dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx)
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
|
||||
struct spdk_dif_error *err_blk)
|
||||
{
|
||||
struct _iov_iter src_iter, dst_iter;
|
||||
uint32_t offset_blocks, data_block_size;
|
||||
@ -734,7 +735,7 @@ dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
memcpy(dst, src, data_block_size);
|
||||
}
|
||||
|
||||
rc = _dif_verify(src + ctx->guard_interval, guard, offset_blocks, ctx, NULL);
|
||||
rc = _dif_verify(src + ctx->guard_interval, guard, offset_blocks, ctx, err_blk);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
@ -749,7 +750,8 @@ dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
|
||||
static int
|
||||
_dif_verify_copy_split(struct _iov_iter *src_iter, struct _iov_iter *dst_iter,
|
||||
uint32_t offset_blocks, const struct spdk_dif_ctx *ctx)
|
||||
uint32_t offset_blocks, const struct spdk_dif_ctx *ctx,
|
||||
struct spdk_dif_error *err_blk)
|
||||
{
|
||||
uint32_t offset_in_block, dst_len, data_block_size;
|
||||
uint16_t guard;
|
||||
@ -787,12 +789,13 @@ _dif_verify_copy_split(struct _iov_iter *src_iter, struct _iov_iter *dst_iter,
|
||||
|
||||
_iov_iter_advance(src_iter, ctx->block_size);
|
||||
|
||||
return _dif_verify(src + ctx->guard_interval, guard, offset_blocks, ctx, NULL);
|
||||
return _dif_verify(src + ctx->guard_interval, guard, offset_blocks, ctx, err_blk);
|
||||
}
|
||||
|
||||
static int
|
||||
dif_verify_copy_split(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx)
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
|
||||
struct spdk_dif_error *err_blk)
|
||||
{
|
||||
struct _iov_iter src_iter, dst_iter;
|
||||
uint32_t offset_blocks;
|
||||
@ -804,7 +807,7 @@ dif_verify_copy_split(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
|
||||
while (offset_blocks < num_blocks &&
|
||||
_iov_iter_cont(&src_iter) && _iov_iter_cont(&dst_iter)) {
|
||||
rc = _dif_verify_copy_split(&src_iter, &dst_iter, offset_blocks, ctx);
|
||||
rc = _dif_verify_copy_split(&src_iter, &dst_iter, offset_blocks, ctx, err_blk);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
@ -816,7 +819,8 @@ dif_verify_copy_split(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
|
||||
int
|
||||
spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx)
|
||||
uint32_t num_blocks, const struct spdk_dif_ctx *ctx,
|
||||
struct spdk_dif_error *err_blk)
|
||||
{
|
||||
uint32_t data_block_size;
|
||||
|
||||
@ -833,9 +837,9 @@ spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
}
|
||||
|
||||
if (_are_iovs_bytes_multiple(iovs, iovcnt, data_block_size)) {
|
||||
return dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, ctx);
|
||||
return dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, ctx, err_blk);
|
||||
} else {
|
||||
return dif_verify_copy_split(iovs, iovcnt, bounce_iov, num_blocks, ctx);
|
||||
return dif_verify_copy_split(iovs, iovcnt, bounce_iov, num_blocks, ctx, err_blk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -747,7 +747,7 @@ dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov
|
||||
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
|
||||
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = ut_data_pattern_verify(iovs, iovcnt, block_size - md_size, 0, num_blocks);
|
||||
@ -892,6 +892,121 @@ dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void)
|
||||
_iov_free_buf(&bounce_iov);
|
||||
}
|
||||
|
||||
static void
|
||||
_dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
|
||||
uint32_t inject_flags, bool dif_loc)
|
||||
{
|
||||
struct spdk_dif_ctx ctx = {};
|
||||
struct spdk_dif_error err_blk = {};
|
||||
uint32_t inject_offset = 0, dif_flags;
|
||||
int rc;
|
||||
|
||||
dif_flags = SPDK_DIF_GUARD_CHECK | SPDK_DIF_APPTAG_CHECK | SPDK_DIF_REFTAG_CHECK;
|
||||
|
||||
rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_ctx_init(&ctx, block_size, md_size, dif_loc, SPDK_DIF_TYPE1, dif_flags,
|
||||
88, 0xFFFF, 0x88);
|
||||
SPDK_CU_ASSERT_FATAL(rc == 0);
|
||||
|
||||
rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_inject_error(bounce_iov, 1, num_blocks, &ctx, inject_flags, &inject_offset);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
rc = spdk_dif_verify_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx, &err_blk);
|
||||
CU_ASSERT(rc != 0);
|
||||
if (inject_flags == SPDK_DIF_DATA_ERROR) {
|
||||
CU_ASSERT(SPDK_DIF_GUARD_ERROR == err_blk.err_type);
|
||||
} else {
|
||||
CU_ASSERT(inject_flags == err_blk.err_type);
|
||||
}
|
||||
CU_ASSERT(inject_offset == err_blk.err_offset);
|
||||
}
|
||||
|
||||
static void
|
||||
dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov,
|
||||
uint32_t block_size, uint32_t md_size, uint32_t num_blocks,
|
||||
uint32_t inject_flags)
|
||||
{
|
||||
/* The case that DIF is contained in the first 8 bytes of metadata. */
|
||||
_dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov,
|
||||
block_size, md_size, num_blocks,
|
||||
inject_flags, false);
|
||||
|
||||
/* The case that DIF is contained in the last 8 bytes of metadata. */
|
||||
_dif_copy_inject_error_and_verify(iovs, iovcnt, bounce_iov,
|
||||
block_size, md_size, num_blocks,
|
||||
inject_flags, true);
|
||||
}
|
||||
|
||||
static void
|
||||
dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test(void)
|
||||
{
|
||||
struct iovec iovs[4], bounce_iov;
|
||||
int i, num_blocks;
|
||||
|
||||
num_blocks = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
_iov_alloc_buf(&iovs[i], 4096 * (i + 1));
|
||||
num_blocks += i + 1;
|
||||
}
|
||||
|
||||
_iov_alloc_buf(&bounce_iov, (4096 + 128) * num_blocks);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
num_blocks, SPDK_DIF_GUARD_ERROR);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
num_blocks, SPDK_DIF_APPTAG_ERROR);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
num_blocks, SPDK_DIF_REFTAG_ERROR);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
num_blocks, SPDK_DIF_DATA_ERROR);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
_iov_free_buf(&iovs[i]);
|
||||
}
|
||||
_iov_free_buf(&bounce_iov);
|
||||
}
|
||||
|
||||
static void
|
||||
dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void)
|
||||
{
|
||||
struct iovec iovs[4], bounce_iov;
|
||||
int i;
|
||||
|
||||
_iov_alloc_buf(&iovs[0], 2048);
|
||||
_iov_alloc_buf(&iovs[1], 2048);
|
||||
_iov_alloc_buf(&iovs[2], 1);
|
||||
_iov_alloc_buf(&iovs[3], 4095);
|
||||
|
||||
_iov_alloc_buf(&bounce_iov, (4096 + 128) * 2);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
2, SPDK_DIF_GUARD_ERROR);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
2, SPDK_DIF_APPTAG_ERROR);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
2, SPDK_DIF_REFTAG_ERROR);
|
||||
|
||||
dif_copy_inject_error_and_verify(iovs, 4, &bounce_iov, 4096 + 128, 128,
|
||||
2, SPDK_DIF_DATA_ERROR);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
_iov_free_buf(&iovs[i]);
|
||||
}
|
||||
_iov_free_buf(&bounce_iov);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@ -955,7 +1070,11 @@ main(int argc, char **argv)
|
||||
CU_add_test(suite, "dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data",
|
||||
dif_copy_sec_512_md_8_prchk_7_multi_iovs_split_data) == NULL ||
|
||||
CU_add_test(suite, "dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits",
|
||||
dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits) == NULL
|
||||
dif_copy_sec_512_md_8_prchk_7_multi_iovs_complex_splits) == NULL ||
|
||||
CU_add_test(suite, "dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test",
|
||||
dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_test) == NULL ||
|
||||
CU_add_test(suite, "dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test",
|
||||
dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test) == NULL
|
||||
) {
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
Loading…
x
Reference in New Issue
Block a user