diff --git a/lib/util/dif.c b/lib/util/dif.c index 59aecb65a..7ac007be0 100644 --- a/lib/util/dif.c +++ b/lib/util/dif.c @@ -1514,38 +1514,25 @@ spdk_dif_set_md_interleave_iovs(struct iovec *iovs, int iovcnt, return iovcnt - dif_sgl.iovcnt; } -int -spdk_dif_generate_stream(struct iovec *iovs, int iovcnt, - uint32_t data_offset, uint32_t data_len, - struct spdk_dif_ctx *ctx) +static int +_dif_sgl_setup_stream(struct _dif_sgl *sgl, uint32_t *_buf_offset, uint32_t *_buf_len, + uint32_t data_offset, uint32_t data_len, + const struct spdk_dif_ctx *ctx) { uint32_t data_block_size, data_unalign, buf_len, buf_offset; - uint32_t len, offset_in_block, offset_blocks; - uint16_t guard = 0; - struct _dif_sgl sgl; - - if (iovs == NULL || iovcnt == 0) { - return -EINVAL; - } data_block_size = ctx->block_size - ctx->md_size; - if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { - guard = ctx->last_guard; - } - data_unalign = ctx->data_offset % data_block_size; /* If the last data block is complete, DIF of the data block is - * inserted in this function. + * inserted or verified in this turn. */ buf_len = ((data_unalign + data_offset + data_len) / data_block_size) * ctx->block_size + ((data_unalign + data_offset + data_len) % data_block_size); buf_len -= data_unalign; - _dif_sgl_init(&sgl, iovs, iovcnt); - - if (!_dif_sgl_is_valid(&sgl, buf_len)) { + if (!_dif_sgl_is_valid(sgl, buf_len)) { return -ERANGE; } @@ -1553,11 +1540,43 @@ spdk_dif_generate_stream(struct iovec *iovs, int iovcnt, ((data_unalign + data_offset) % data_block_size); buf_offset -= data_unalign; - _dif_sgl_advance(&sgl, buf_offset); + _dif_sgl_advance(sgl, buf_offset); buf_len -= buf_offset; buf_offset += data_unalign; + *_buf_offset = buf_offset; + *_buf_len = buf_len; + + return 0; +} + +int +spdk_dif_generate_stream(struct iovec *iovs, int iovcnt, + uint32_t data_offset, uint32_t data_len, + struct spdk_dif_ctx *ctx) +{ + uint32_t buf_len = 0, buf_offset = 0; + uint32_t len, offset_in_block, offset_blocks; + uint16_t guard = 0; + struct _dif_sgl sgl; + int rc; + + if (iovs == NULL || iovcnt == 0) { + return -EINVAL; + } + + if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { + guard = ctx->last_guard; + } + + _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; @@ -1582,7 +1601,7 @@ spdk_dif_verify_stream(struct iovec *iovs, int iovcnt, struct spdk_dif_ctx *ctx, struct spdk_dif_error *err_blk) { - uint32_t data_block_size, data_unalign, buf_len, buf_offset; + uint32_t buf_len = 0, buf_offset = 0; uint32_t len, offset_in_block, offset_blocks; uint16_t guard = 0; struct _dif_sgl sgl; @@ -1592,36 +1611,17 @@ spdk_dif_verify_stream(struct iovec *iovs, int iovcnt, return -EINVAL; } - data_block_size = ctx->block_size - ctx->md_size; - if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { guard = ctx->last_guard; } - data_unalign = ctx->data_offset % data_block_size; - - /* If the last data block is complete, DIF of the data block is - * verified in this function.; - */ - buf_len = ((data_unalign + data_offset + data_len) / data_block_size) * ctx->block_size + - ((data_unalign + data_offset + data_len) % data_block_size); - buf_len -= data_unalign; - _dif_sgl_init(&sgl, iovs, iovcnt); - if (!_dif_sgl_is_valid(&sgl, buf_len)) { - return -ERANGE; + rc = _dif_sgl_setup_stream(&sgl, &buf_offset, &buf_len, data_offset, data_len, ctx); + if (rc != 0) { + return rc; } - buf_offset = ((data_unalign + data_offset) / data_block_size) * ctx->block_size + - ((data_unalign + data_offset) % data_block_size); - buf_offset -= data_unalign; - - _dif_sgl_advance(&sgl, buf_offset); - buf_len -= buf_offset; - - buf_offset += data_unalign; - 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;