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 <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/434150 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@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
045e77c235
commit
65624bd5e4
@ -68,7 +68,7 @@ struct spdk_dif_ctx {
|
|||||||
/** Metadata size */
|
/** Metadata size */
|
||||||
uint32_t md_size;
|
uint32_t md_size;
|
||||||
|
|
||||||
/** Interval for guard computation */
|
/** Interval for guard computation for DIF */
|
||||||
uint32_t guard_interval;
|
uint32_t guard_interval;
|
||||||
|
|
||||||
/** DIF type */
|
/** DIF type */
|
||||||
@ -108,6 +108,8 @@ struct spdk_dif_error {
|
|||||||
* \param ctx DIF context.
|
* \param ctx DIF context.
|
||||||
* \param block_size Block size in a block.
|
* \param block_size Block size in a block.
|
||||||
* \param md_size Metadata 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.
|
* \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.
|
* If false, DIF is in the first 8 bytes of metadata.
|
||||||
* \param dif_type Type of DIF.
|
* \param dif_type Type of DIF.
|
||||||
@ -120,7 +122,7 @@ struct spdk_dif_error {
|
|||||||
* \return 0 on success and negated errno otherwise.
|
* \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,
|
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);
|
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,
|
int spdk_dif_inject_error(struct iovec *iovs, int iovcnt, uint32_t num_blocks,
|
||||||
const struct spdk_dif_ctx *ctx, uint32_t inject_flags,
|
const struct spdk_dif_ctx *ctx, uint32_t inject_flags,
|
||||||
uint32_t *inject_offset);
|
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 */
|
#endif /* SPDK_DIF_H */
|
||||||
|
258
lib/util/dif.c
258
lib/util/dif.c
@ -159,27 +159,36 @@ _dif_is_disabled(enum spdk_dif_type dif_type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
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) {
|
if (dif_loc) {
|
||||||
/* For metadata formats with more than 8 bytes, if the DIF is
|
/* For metadata formats with more than 8 bytes, if the DIF is
|
||||||
* contained in the last 8 bytes of metadata, then the CRC
|
* contained in the last 8 bytes of metadata, then the CRC
|
||||||
* covers all metadata up to but excluding these last 8 bytes.
|
* 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 {
|
} else {
|
||||||
/* For metadata formats with more than 8 bytes, if the DIF is
|
/* For metadata formats with more than 8 bytes, if the DIF is
|
||||||
* contained in the first 8 bytes of metadata, then the CRC
|
* contained in the first 8 bytes of metadata, then the CRC
|
||||||
* does not cover any metadata.
|
* does not cover any metadata.
|
||||||
*/
|
*/
|
||||||
return block_size - md_size;
|
if (md_interleave) {
|
||||||
|
return block_size - md_size;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size,
|
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)
|
uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag)
|
||||||
{
|
{
|
||||||
if (md_size < sizeof(struct spdk_dif)) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block_size < md_size) {
|
if (md_interleave) {
|
||||||
SPDK_ERRLOG("Block size is smaller than DIF size.\n");
|
if (block_size < md_size) {
|
||||||
return -EINVAL;
|
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)) {
|
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->block_size = block_size;
|
||||||
ctx->md_size = md_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_type = dif_type;
|
||||||
ctx->dif_flags = dif_flags;
|
ctx->dif_flags = dif_flags;
|
||||||
ctx->init_ref_tag = init_ref_tag;
|
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;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -145,7 +145,7 @@ _dif_generate_and_verify(struct iovec *iov,
|
|||||||
rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1);
|
rc = ut_data_pattern_generate(iov, 1, block_size, md_size, 1);
|
||||||
CU_ASSERT(rc == 0);
|
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_type = dif_type;
|
||||||
ctx.dif_flags = dif_flags;
|
ctx.dif_flags = dif_flags;
|
||||||
@ -270,7 +270,7 @@ dif_sec_512_md_0_error_test(void)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Metadata size is 0. */
|
/* 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);
|
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);
|
rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
init_ref_tag, apptag_mask, app_tag);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
rc = ut_data_pattern_generate(iovs, iovcnt, block_size, md_size, num_blocks);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
init_ref_tag, apptag_mask, app_tag);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
rc = ut_data_pattern_generate(iovs, iovcnt, block_size - md_size, 0, num_blocks);
|
||||||
CU_ASSERT(rc == 0);
|
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);
|
88, 0xFFFF, 0x88);
|
||||||
SPDK_CU_ASSERT_FATAL(rc == 0);
|
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);
|
_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
|
int
|
||||||
main(int argc, char **argv)
|
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",
|
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 ||
|
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",
|
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();
|
CU_cleanup_registry();
|
||||||
return CU_get_error();
|
return CU_get_error();
|
||||||
|
Loading…
Reference in New Issue
Block a user