From 65624bd5e4e0a3cc26c381107c595695655e9d4b Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Wed, 9 Jan 2019 08:07:08 +0900 Subject: [PATCH] dix: Generate DIF for separate metadata payload This patch adds APIs to generate and verify DIF for SGL payload with separate metadata as byte alignment and granularity. Change-Id: I4e553c9b6f8c96e576a69115002963d32379d439 Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/434150 Tested-by: SPDK CI Jenkins Chandler-Test-Pool: SPDK Automated Test System Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris --- include/spdk/dif.h | 34 +++- lib/util/dif.c | 258 +++++++++++++++++++++++++++++- test/unit/lib/util/dif.c/dif_ut.c | 194 +++++++++++++++++++++- 3 files changed, 469 insertions(+), 17 deletions(-) diff --git a/include/spdk/dif.h b/include/spdk/dif.h index 255e643af..d64fd4625 100644 --- a/include/spdk/dif.h +++ b/include/spdk/dif.h @@ -68,7 +68,7 @@ struct spdk_dif_ctx { /** Metadata size */ uint32_t md_size; - /** Interval for guard computation */ + /** Interval for guard computation for DIF */ uint32_t guard_interval; /** DIF type */ @@ -108,6 +108,8 @@ struct spdk_dif_error { * \param ctx DIF context. * \param block_size Block size in a block. * \param md_size Metadata size in a block. + * \param md_interleave If true, metadata is interleaved with block data. + * If false, metadata is separated with block data. * \param dif_loc DIF location. If true, DIF is set in the last 8 bytes of metadata. * If false, DIF is in the first 8 bytes of metadata. * \param dif_type Type of DIF. @@ -120,7 +122,7 @@ struct spdk_dif_error { * \return 0 on success and negated errno otherwise. */ int spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, - bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, + bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag); /** @@ -196,4 +198,32 @@ int spdk_dif_verify_copy(struct iovec *iovs, int iovcnt, struct iovec *bounce_io int spdk_dif_inject_error(struct iovec *iovs, int iovcnt, uint32_t num_blocks, const struct spdk_dif_ctx *ctx, uint32_t inject_flags, uint32_t *inject_offset); + +/** + * Generate DIF for separate metadata payload. + * + * \param iovs iovec array describing the LBA payload. + * \params iovcnt Number of elements in iovs. + * \param md_iov A contiguous buffer for metadata. + * \param num_blocks Number of blocks of the separate metadata payload. + * \param ctx DIF context. + * + * \return 0 on success and negated errno otherwise. + */ +int spdk_dix_generate(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx); + +/** + * Verify DIF for separate metadata payload. + * + * \param iovs iovec array describing the LBA payload. + * \params iovcnt Number of elements in iovs. + * \param md_iov A contiguous buffer for metadata. + * \param num_blocks Number of blocks of the separate metadata payload. + * \param ctx DIF context. + * + * \return 0 on success and negated errno otherwise. + */ +int spdk_dix_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx); #endif /* SPDK_DIF_H */ diff --git a/lib/util/dif.c b/lib/util/dif.c index e8d5424f0..099981ce5 100644 --- a/lib/util/dif.c +++ b/lib/util/dif.c @@ -159,27 +159,36 @@ _dif_is_disabled(enum spdk_dif_type dif_type) } } + static uint32_t -_get_dif_guard_interval(uint32_t block_size, uint32_t md_size, bool dif_loc) +_get_guard_interval(uint32_t block_size, uint32_t md_size, bool dif_loc, bool md_interleave) { if (dif_loc) { /* For metadata formats with more than 8 bytes, if the DIF is * contained in the last 8 bytes of metadata, then the CRC * covers all metadata up to but excluding these last 8 bytes. */ - return block_size - sizeof(struct spdk_dif); + if (md_interleave) { + return block_size - sizeof(struct spdk_dif); + } else { + return md_size - sizeof(struct spdk_dif); + } } else { /* For metadata formats with more than 8 bytes, if the DIF is * contained in the first 8 bytes of metadata, then the CRC * does not cover any metadata. */ - return block_size - md_size; + if (md_interleave) { + return block_size - md_size; + } else { + return 0; + } } } int spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, - bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, + bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) { if (md_size < sizeof(struct spdk_dif)) { @@ -187,9 +196,16 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz return -EINVAL; } - if (block_size < md_size) { - SPDK_ERRLOG("Block size is smaller than DIF size.\n"); - return -EINVAL; + if (md_interleave) { + if (block_size < md_size) { + SPDK_ERRLOG("Block size is smaller than DIF size.\n"); + return -EINVAL; + } + } else { + if (block_size == 0 || (block_size % 512) != 0) { + SPDK_ERRLOG("Zero block size is not allowed\n"); + return -EINVAL; + } } if (!_dif_type_is_valid(dif_type, dif_flags)) { @@ -199,7 +215,7 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz ctx->block_size = block_size; ctx->md_size = md_size; - ctx->guard_interval = _get_dif_guard_interval(block_size, md_size, dif_loc); + ctx->guard_interval = _get_guard_interval(block_size, md_size, dif_loc, md_interleave); ctx->dif_type = dif_type; ctx->dif_flags = dif_flags; ctx->init_ref_tag = init_ref_tag; @@ -987,3 +1003,229 @@ spdk_dif_inject_error(struct iovec *iovs, int iovcnt, uint32_t num_blocks, return 0; } + +static void +dix_generate(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx) +{ + struct _iov_iter data_iter, md_iter; + uint32_t offset_blocks; + uint16_t guard; + void *data_buf, *md_buf; + + offset_blocks = 0; + _iov_iter_init(&data_iter, iovs, iovcnt); + _iov_iter_init(&md_iter, md_iov, 1); + + while (offset_blocks < num_blocks && + _iov_iter_cont(&data_iter) && _iov_iter_cont(&md_iter)) { + + _iov_iter_get_buf(&data_iter, &data_buf, NULL); + _iov_iter_get_buf(&md_iter, &md_buf, NULL); + + guard = 0; + if (ctx->dif_flags & SPDK_DIF_GUARD_CHECK) { + guard = spdk_crc16_t10dif(0, data_buf, ctx->block_size); + guard = spdk_crc16_t10dif(guard, md_buf, ctx->guard_interval); + } + + _dif_generate(md_buf + ctx->guard_interval, guard, offset_blocks, ctx); + + _iov_iter_advance(&data_iter, ctx->block_size); + _iov_iter_advance(&md_iter, ctx->md_size); + offset_blocks++; + } +} + +static void +_dix_generate_split(struct _iov_iter *data_iter, struct _iov_iter *md_iter, + uint32_t offset_blocks, const struct spdk_dif_ctx *ctx) +{ + uint32_t offset_in_block, data_buf_len; + uint16_t guard; + void *data_buf, *md_buf; + + _iov_iter_get_buf(md_iter, &md_buf, NULL); + + guard = 0; + if (ctx->dif_flags & SPDK_DIF_GUARD_CHECK) { + guard = spdk_crc16_t10dif(0, md_buf, ctx->guard_interval); + } + + offset_in_block = 0; + + while (offset_in_block < ctx->block_size && _iov_iter_cont(data_iter)) { + _iov_iter_get_buf(data_iter, &data_buf, &data_buf_len); + data_buf_len = spdk_min(data_buf_len, ctx->block_size - offset_in_block); + + if (ctx->dif_flags & SPDK_DIF_GUARD_CHECK) { + guard = spdk_crc16_t10dif(guard, data_buf, data_buf_len); + } + + _iov_iter_advance(data_iter, data_buf_len); + offset_in_block += data_buf_len; + } + + _iov_iter_advance(md_iter, ctx->md_size); + + _dif_generate(md_buf + ctx->guard_interval, guard, offset_blocks, ctx); +} + +static void +dix_generate_split(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx) +{ + struct _iov_iter data_iter, md_iter; + uint32_t offset_blocks; + + offset_blocks = 0; + _iov_iter_init(&data_iter, iovs, iovcnt); + _iov_iter_init(&md_iter, md_iov, 1); + + while (offset_blocks < num_blocks && + _iov_iter_cont(&data_iter) && _iov_iter_cont(&md_iter)) { + _dix_generate_split(&data_iter, &md_iter, offset_blocks, ctx); + offset_blocks++; + } +} + +int +spdk_dix_generate(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx) +{ + if (!_are_iovs_valid(iovs, iovcnt, ctx->block_size * num_blocks) || + !_are_iovs_valid(md_iov, 1, ctx->md_size * num_blocks)) { + SPDK_ERRLOG("Size of iovec array is not valid.\n"); + return -EINVAL; + } + + if (_dif_is_disabled(ctx->dif_type)) { + return 0; + } + + if (_are_iovs_bytes_multiple(iovs, iovcnt, ctx->block_size)) { + dix_generate(iovs, iovcnt, md_iov, num_blocks, ctx); + } else { + dix_generate_split(iovs, iovcnt, md_iov, num_blocks, ctx); + } + + return 0; +} + +static int +dix_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx) +{ + struct _iov_iter data_iter, md_iter; + uint32_t offset_blocks; + uint16_t guard; + void *data_buf, *md_buf; + int rc; + + offset_blocks = 0; + _iov_iter_init(&data_iter, iovs, iovcnt); + _iov_iter_init(&md_iter, md_iov, 1); + + while (offset_blocks < num_blocks && + _iov_iter_cont(&data_iter) && _iov_iter_cont(&md_iter)) { + + _iov_iter_get_buf(&data_iter, &data_buf, NULL); + _iov_iter_get_buf(&md_iter, &md_buf, NULL); + + guard = 0; + if (ctx->dif_flags & SPDK_DIF_GUARD_CHECK) { + guard = spdk_crc16_t10dif(0, data_buf, ctx->block_size); + guard = spdk_crc16_t10dif(guard, md_buf, ctx->guard_interval); + } + + rc = _dif_verify(md_buf + ctx->guard_interval, guard, offset_blocks, ctx, NULL); + if (rc != 0) { + return rc; + } + + _iov_iter_advance(&data_iter, ctx->block_size); + _iov_iter_advance(&md_iter, ctx->md_size); + offset_blocks++; + } + + return 0; +} + +static int +_dix_verify_split(struct _iov_iter *data_iter, struct _iov_iter *md_iter, + uint32_t offset_blocks, const struct spdk_dif_ctx *ctx) +{ + uint32_t offset_in_block, data_buf_len; + uint16_t guard; + void *data_buf, *md_buf; + + _iov_iter_get_buf(md_iter, &md_buf, NULL); + + guard = 0; + if (ctx->dif_flags & SPDK_DIF_GUARD_CHECK) { + guard = spdk_crc16_t10dif(0, md_buf, ctx->guard_interval); + } + + offset_in_block = 0; + + while (offset_in_block < ctx->block_size && _iov_iter_cont(data_iter)) { + _iov_iter_get_buf(data_iter, &data_buf, &data_buf_len); + data_buf_len = spdk_min(data_buf_len, ctx->block_size - offset_in_block); + + if (ctx->dif_flags & SPDK_DIF_GUARD_CHECK) { + guard = spdk_crc16_t10dif(guard, data_buf, data_buf_len); + } + + _iov_iter_advance(data_iter, data_buf_len); + offset_in_block += data_buf_len; + } + + _iov_iter_advance(md_iter, ctx->md_size); + + return _dif_verify(md_buf + ctx->guard_interval, guard, offset_blocks, ctx, NULL); +} + +static int +dix_verify_split(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx) +{ + struct _iov_iter data_iter, md_iter; + uint32_t offset_blocks; + int rc; + + offset_blocks = 0; + _iov_iter_init(&data_iter, iovs, iovcnt); + _iov_iter_init(&md_iter, md_iov, 1); + + while (offset_blocks < num_blocks && + _iov_iter_cont(&data_iter) && _iov_iter_cont(&md_iter)) { + rc = _dix_verify_split(&data_iter, &md_iter, offset_blocks, ctx); + if (rc != 0) { + return rc; + } + offset_blocks++; + } + + return 0; +} + +int +spdk_dix_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t num_blocks, const struct spdk_dif_ctx *ctx) +{ + if (!_are_iovs_valid(iovs, iovcnt, ctx->block_size * num_blocks) || + !_are_iovs_valid(md_iov, 1, ctx->md_size * num_blocks)) { + SPDK_ERRLOG("Size of iovec array is not valid.\n"); + return -EINVAL; + } + + if (_dif_is_disabled(ctx->dif_type)) { + return 0; + } + + if (_are_iovs_bytes_multiple(iovs, iovcnt, ctx->block_size)) { + return dix_verify(iovs, iovcnt, md_iov, num_blocks, ctx); + } else { + return dix_verify_split(iovs, iovcnt, md_iov, num_blocks, ctx); + } +} diff --git a/test/unit/lib/util/dif.c/dif_ut.c b/test/unit/lib/util/dif.c/dif_ut.c index 20985ddab..90399583f 100644 --- a/test/unit/lib/util/dif.c/dif_ut.c +++ b/test/unit/lib/util/dif.c/dif_ut.c @@ -145,7 +145,7 @@ _dif_generate_and_verify(struct iovec *iov, rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1); CU_ASSERT(rc == 0); - guard_interval = _get_dif_guard_interval(block_size, md_size, dif_loc); + guard_interval = _get_guard_interval(block_size, md_size, dif_loc, true); ctx.dif_type = dif_type; ctx.dif_flags = dif_flags; @@ -270,7 +270,7 @@ dif_sec_512_md_0_error_test(void) int rc; /* Metadata size is 0. */ - rc = spdk_dif_ctx_init(&ctx, 512, 0, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); + rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); CU_ASSERT(rc != 0); } @@ -286,7 +286,7 @@ dif_generate_and_verify(struct iovec *iovs, int iovcnt, rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); CU_ASSERT(rc == 0); - rc = spdk_dif_ctx_init(&ctx, block_size, md_size, dif_loc, dif_type, dif_flags, + rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, init_ref_tag, apptag_mask, app_tag); CU_ASSERT(rc == 0); @@ -582,7 +582,7 @@ _dif_inject_error_and_verify(struct iovec *iovs, int iovcnt, rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks); CU_ASSERT(rc == 0); - rc = spdk_dif_ctx_init(&ctx, block_size, md_size, dif_loc, + rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88); CU_ASSERT(rc == 0); @@ -740,7 +740,7 @@ dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov 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, dif_type, dif_flags, + rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, init_ref_tag, apptag_mask, app_tag); CU_ASSERT(rc == 0); @@ -907,7 +907,7 @@ _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec * 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, + rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88); SPDK_CU_ASSERT_FATAL(rc == 0); @@ -1007,6 +1007,175 @@ dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test(void) _iov_free_buf(&bounce_iov); } +static void +dix_sec_512_md_0_error(void) +{ + struct spdk_dif_ctx ctx; + int rc; + + rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); + CU_ASSERT(rc != 0); +} + +static void +dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, + uint32_t block_size, uint32_t md_size, uint32_t num_blocks, + bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, + uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag) +{ + struct spdk_dif_ctx ctx; + int rc; + + rc = ut_data_pattern_generate(iovs, iovcnt, block_size, 0, num_blocks); + CU_ASSERT(rc == 0); + + rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, + init_ref_tag, apptag_mask, app_tag); + CU_ASSERT(rc == 0); + + rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); + CU_ASSERT(rc == 0); + + rc = spdk_dix_verify(iovs, iovcnt, md_iov, num_blocks, &ctx); + CU_ASSERT(rc == 0); + + rc = ut_data_pattern_verify(iovs, iovcnt, block_size, 0, num_blocks); + CU_ASSERT(rc == 0); +} + +static void +dix_sec_512_md_8_prchk_0_single_iov(void) +{ + struct iovec iov, md_iov; + + _iov_alloc_buf(&iov, 512 * 4); + _iov_alloc_buf(&md_iov, 8 * 4); + + dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, 0, 0, 0, 0); + dix_generate_and_verify(&iov, 1, &md_iov, 512, 8, 4, true, SPDK_DIF_TYPE1, 0, 0, 0, 0); + + _iov_free_buf(&iov); + _iov_free_buf(&md_iov); +} + +static void +dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs(void) +{ + struct iovec iovs[4], md_iov; + int i, num_blocks; + + num_blocks = 0; + + for (i = 0; i < 4; i++) { + _iov_alloc_buf(&iovs[i], 512 * (i + 1)); + num_blocks += i + 1; + } + _iov_alloc_buf(&md_iov, 8 * num_blocks); + + dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, + 0, 22, 0xFFFF, 0x22); + + dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, + SPDK_DIF_GUARD_CHECK, 22, 0xFFFF, 0x22); + + dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, + SPDK_DIF_APPTAG_CHECK, 22, 0xFFFF, 0x22); + + dix_generate_and_verify(iovs, 4, &md_iov, 512, 8, num_blocks, false, SPDK_DIF_TYPE1, + SPDK_DIF_REFTAG_CHECK, 22, 0xFFFF, 0x22); + + for (i = 0; i < 4; i++) { + _iov_free_buf(&iovs[i]); + } + _iov_free_buf(&md_iov); +} + +static void +dix_sec_4096_md_128_prchk_7_multi_iovs(void) +{ + struct iovec iovs[4], md_iov; + uint32_t dif_flags; + int i, num_blocks; + + dif_flags = SPDK_DIF_GUARD_CHECK | SPDK_DIF_APPTAG_CHECK | SPDK_DIF_REFTAG_CHECK; + + num_blocks = 0; + + for (i = 0; i < 4; i++) { + _iov_alloc_buf(&iovs[i], 4096 * (i + 1)); + num_blocks += i + 1; + } + _iov_alloc_buf(&md_iov, 128 * num_blocks); + + dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, false, SPDK_DIF_TYPE1, + dif_flags, 22, 0xFFFF, 0x22); + dix_generate_and_verify(iovs, 4, &md_iov, 4096, 128, num_blocks, true, SPDK_DIF_TYPE1, + dif_flags, 22, 0xFFFF, 0x22); + + for (i = 0; i < 4; i++) { + _iov_free_buf(&iovs[i]); + } + _iov_free_buf(&md_iov); +} + +static void +dix_sec_512_md_8_prchk_7_multi_iovs_split_data(void) +{ + struct iovec iovs[2], md_iov; + uint32_t dif_flags; + + dif_flags = SPDK_DIF_GUARD_CHECK | SPDK_DIF_APPTAG_CHECK | SPDK_DIF_REFTAG_CHECK; + + _iov_alloc_buf(&iovs[0], 256); + _iov_alloc_buf(&iovs[1], 256); + _iov_alloc_buf(&md_iov, 8); + + dix_generate_and_verify(iovs, 2, &md_iov, 512, 8, 1, false, SPDK_DIF_TYPE1, + dif_flags, 22, 0xFFFF, 0x22); + + _iov_free_buf(&iovs[0]); + _iov_free_buf(&iovs[1]); + _iov_free_buf(&md_iov); +} + +static void +dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits(void) +{ + struct iovec iovs[6], md_iov; + uint32_t dif_flags; + int i; + + dif_flags = SPDK_DIF_GUARD_CHECK | SPDK_DIF_APPTAG_CHECK | SPDK_DIF_REFTAG_CHECK; + + /* data[0][255:0] */ + _iov_alloc_buf(&iovs[0], 256); + + /* data[0][511:256], data[1][255:0] */ + _iov_alloc_buf(&iovs[1], 256 + 256); + + /* data[1][382:256] */ + _iov_alloc_buf(&iovs[2], 128); + + /* data[1][383] */ + _iov_alloc_buf(&iovs[3], 1); + + /* data[1][510:384] */ + _iov_alloc_buf(&iovs[4], 126); + + /* data[1][511], data[2][511:0], data[3][511:0] */ + _iov_alloc_buf(&iovs[5], 1 + 512 * 2); + + _iov_alloc_buf(&md_iov, 8 * 4); + + dix_generate_and_verify(iovs, 6, &md_iov, 512, 8, 4, false, SPDK_DIF_TYPE1, + dif_flags, 22, 0xFFFF, 0x22); + + for (i = 0; i < 6; i++) { + _iov_free_buf(&iovs[i]); + } + _iov_free_buf(&md_iov); +} + int main(int argc, char **argv) { @@ -1074,7 +1243,18 @@ main(int argc, char **argv) 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 + dif_copy_sec_4096_md_128_inject_1_2_4_8_multi_iovs_split_test) == NULL || + CU_add_test(suite, "dix_sec_512_md_0_error", dix_sec_512_md_0_error) == NULL || + CU_add_test(suite, "dix_sec_512_md_8_prchk_0_single_iov", + dix_sec_512_md_8_prchk_0_single_iov) == NULL || + CU_add_test(suite, "dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs", + dix_sec_512_md_8_prchk_0_1_2_4_multi_iovs) == NULL || + CU_add_test(suite, "dix_sec_4096_md_128_prchk_7_multi_iovs", + dix_sec_4096_md_128_prchk_7_multi_iovs) == NULL || + CU_add_test(suite, "dix_sec_512_md_8_prchk_7_multi_iovs_split_data", + dix_sec_512_md_8_prchk_7_multi_iovs_split_data) == NULL || + CU_add_test(suite, "dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits", + dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits) == NULL ) { CU_cleanup_registry(); return CU_get_error();