dif: Separate _dif_generate_split into three parts
For NVMe/TCP target, data segments which correspond to H2C or C2H PDU will have any alignment, and _dif_generate_split will have to process partial data data block, particularly the following types: - start and end are both within a data block. - start is within a data block, and end is at the end of a block On the other hand, _dif_generate_split had assumed that passed block is always a complete block. To process the above types, separating guard computation, DIF generation, and DIF copy into three parts will be helpful and is done in this patch. Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: I0171d9021837b9a4b425370293cef45dbe7500e8 Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/458225 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
parent
f1344911ea
commit
27707953ec
@ -328,31 +328,36 @@ _dif_generate_split(struct _dif_sgl *sgl, uint32_t offset_blocks,
|
||||
}
|
||||
offset_in_block = 0;
|
||||
|
||||
/* Compute CRC over split logical block data. */
|
||||
while (offset_in_block < ctx->guard_interval) {
|
||||
_dif_sgl_get_buf(sgl, &buf, &buf_len);
|
||||
buf_len = spdk_min(buf_len, ctx->guard_interval - offset_in_block);
|
||||
|
||||
if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
|
||||
guard = spdk_crc16_t10dif(guard, buf, buf_len);
|
||||
}
|
||||
|
||||
_dif_sgl_advance(sgl, buf_len);
|
||||
offset_in_block += buf_len;
|
||||
}
|
||||
|
||||
/* If a whole logical block data is parsed, generate DIF
|
||||
* and save it to the temporary DIF area.
|
||||
*/
|
||||
_dif_generate(&dif, guard, offset_blocks, ctx);
|
||||
|
||||
/* Copy generated DIF field to the split DIF field, and then
|
||||
* skip metadata field after DIF field (if any).
|
||||
*/
|
||||
while (offset_in_block < ctx->block_size) {
|
||||
_dif_sgl_get_buf(sgl, &buf, &buf_len);
|
||||
|
||||
if (offset_in_block < ctx->guard_interval) {
|
||||
buf_len = spdk_min(buf_len, ctx->guard_interval - offset_in_block);
|
||||
|
||||
if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) {
|
||||
/* Compute CRC over split logical block data. */
|
||||
guard = spdk_crc16_t10dif(guard, buf, buf_len);
|
||||
}
|
||||
|
||||
if (offset_in_block + buf_len == ctx->guard_interval) {
|
||||
/* If a whole logical block data is parsed, generate DIF
|
||||
* and save it to the temporary DIF area.
|
||||
*/
|
||||
_dif_generate(&dif, guard, offset_blocks, ctx);
|
||||
}
|
||||
} else if (offset_in_block < ctx->guard_interval + sizeof(struct spdk_dif)) {
|
||||
/* Copy generated DIF to the split DIF field. */
|
||||
if (offset_in_block < ctx->guard_interval + sizeof(struct spdk_dif)) {
|
||||
offset_in_dif = offset_in_block - ctx->guard_interval;
|
||||
buf_len = spdk_min(buf_len, sizeof(struct spdk_dif) - offset_in_dif);
|
||||
|
||||
memcpy(buf, ((uint8_t *)&dif) + offset_in_dif, buf_len);
|
||||
} else {
|
||||
/* Skip metadata field after DIF field. */
|
||||
buf_len = spdk_min(buf_len, ctx->block_size - offset_in_block);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user