dif: Factor out core logic to generate and verify DIF for each split block

This patch factors out the core logic to generate and verify DIF
for each split extended logical block.

This patch reduces nesting and clarify the core logic.

Change-Id: I6adf36fb86fafef8a4235021f77a1d99a0d63c8a
Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/437795
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:
Shuhei Matsumoto 2018-12-19 10:26:36 +09:00 committed by Jim Harris
parent f9cbc493dc
commit 0a3cdcf3c3

View File

@ -210,37 +210,21 @@ dif_generate(struct iovec *iovs, int iovcnt,
}
static void
dif_generate_split(struct iovec *iovs, int iovcnt,
uint32_t block_size, uint32_t guard_interval, uint32_t num_blocks,
_dif_generate_split(struct _iov_iter *iter,
uint32_t block_size, uint32_t guard_interval,
enum spdk_dif_type dif_type, uint32_t dif_flags,
uint32_t init_ref_tag, uint16_t app_tag)
uint32_t ref_tag, uint16_t app_tag)
{
struct _iov_iter iter;
uint32_t offset_blocks, offset_in_block, offset_in_dif;
uint32_t buf_len, ref_tag;
uint32_t offset_in_block, offset_in_dif, buf_len;
void *buf;
uint16_t guard;
struct spdk_dif dif = {};
offset_blocks = 0;
_iov_iter_init(&iter, iovs, iovcnt);
while (offset_blocks < num_blocks && _iov_iter_cont(&iter)) {
/* For type 1 and 2, the reference tag is incremented for each
* subsequent logical block. For type 3, the reference tag
* remains the same as the initial reference tag.
*/
if (dif_type != SPDK_DIF_TYPE3) {
ref_tag = init_ref_tag + offset_blocks;
} else {
ref_tag = init_ref_tag;
}
guard = 0;
offset_in_block = 0;
while (offset_in_block < block_size && _iov_iter_cont(&iter)) {
_iov_iter_get_buf(&iter, &buf, &buf_len);
while (offset_in_block < block_size && _iov_iter_cont(iter)) {
_iov_iter_get_buf(iter, &buf, &buf_len);
if (offset_in_block < guard_interval) {
buf_len = spdk_min(buf_len, guard_interval - offset_in_block);
@ -267,9 +251,37 @@ dif_generate_split(struct iovec *iovs, int iovcnt,
buf_len = spdk_min(buf_len, block_size - offset_in_block);
}
_iov_iter_advance(&iter, buf_len);
_iov_iter_advance(iter, buf_len);
offset_in_block += buf_len;
}
}
static void
dif_generate_split(struct iovec *iovs, int iovcnt,
uint32_t block_size, uint32_t guard_interval, uint32_t num_blocks,
enum spdk_dif_type dif_type, uint32_t dif_flags,
uint32_t init_ref_tag, uint16_t app_tag)
{
struct _iov_iter iter;
uint32_t offset_blocks, ref_tag;
offset_blocks = 0;
_iov_iter_init(&iter, iovs, iovcnt);
while (offset_blocks < num_blocks && _iov_iter_cont(&iter)) {
/* For type 1 and 2, the reference tag is incremented for each
* subsequent logical block. For type 3, the reference tag
* remains the same as the initial reference tag.
*/
if (dif_type != SPDK_DIF_TYPE3) {
ref_tag = init_ref_tag + offset_blocks;
} else {
ref_tag = init_ref_tag;
}
_dif_generate_split(&iter, block_size, guard_interval,
dif_type, dif_flags, ref_tag, app_tag);
offset_blocks++;
}
}
@ -437,38 +449,21 @@ dif_verify(struct iovec *iovs, int iovcnt,
}
static int
dif_verify_split(struct iovec *iovs, int iovcnt,
uint32_t block_size, uint32_t guard_interval, uint32_t num_blocks,
_dif_verify_split(struct _iov_iter *iter,
uint32_t block_size, uint32_t guard_interval,
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 ref_tag, uint16_t apptag_mask, uint16_t app_tag)
{
struct _iov_iter iter;
uint32_t offset_blocks, offset_in_block, offset_in_dif;
uint32_t buf_len, ref_tag = 0;
int rc;
uint32_t offset_in_block, offset_in_dif, buf_len;
void *buf;
uint16_t guard;
struct spdk_dif dif = {};
offset_blocks = 0;
_iov_iter_init(&iter, iovs, iovcnt);
while (offset_blocks < num_blocks && _iov_iter_cont(&iter)) {
/* For type 1 and 2, the reference tag is incremented for each
* subsequent logical block. For type 3, the reference tag
* remains the same as the initial reference tag.
*/
if (dif_type != SPDK_DIF_TYPE3) {
ref_tag = init_ref_tag + offset_blocks;
} else {
ref_tag = init_ref_tag;
}
guard = 0;
offset_in_block = 0;
while (offset_in_block < block_size && _iov_iter_cont(&iter)) {
_iov_iter_get_buf(&iter, &buf, &buf_len);
while (offset_in_block < block_size && _iov_iter_cont(iter)) {
_iov_iter_get_buf(iter, &buf, &buf_len);
if (offset_in_block < guard_interval) {
buf_len = spdk_min(buf_len, guard_interval - offset_in_block);
@ -488,13 +483,42 @@ dif_verify_split(struct iovec *iovs, int iovcnt,
buf_len = spdk_min(buf_len, block_size - offset_in_block);
}
_iov_iter_advance(&iter, buf_len);
_iov_iter_advance(iter, buf_len);
offset_in_block += buf_len;
}
rc = _dif_verify(&dif, dif_type, dif_flags, guard, ref_tag, apptag_mask, app_tag);
return _dif_verify(&dif, dif_type, dif_flags, guard, ref_tag, apptag_mask, app_tag);
}
static int
dif_verify_split(struct iovec *iovs, int iovcnt,
uint32_t block_size, uint32_t guard_interval, uint32_t num_blocks,
enum spdk_dif_type dif_type, uint32_t dif_flags,
uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag)
{
struct _iov_iter iter;
uint32_t offset_blocks;
uint32_t ref_tag;
int rc;
offset_blocks = 0;
_iov_iter_init(&iter, iovs, iovcnt);
while (offset_blocks < num_blocks && _iov_iter_cont(&iter)) {
/* For type 1 and 2, the reference tag is incremented for each
* subsequent logical block. For type 3, the reference tag
* remains the same as the initial reference tag.
*/
if (dif_type != SPDK_DIF_TYPE3) {
ref_tag = init_ref_tag + offset_blocks;
} else {
ref_tag = init_ref_tag;
}
rc = _dif_verify_split(&iter, block_size, guard_interval, dif_type, dif_flags,
ref_tag, apptag_mask, app_tag);
if (rc != 0) {
return 0;
return rc;
}
offset_blocks++;