Commit 0a3cdcf3 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Jim Harris
Browse files

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: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/437795


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
parent f9cbc493
Loading
Loading
Loading
Loading
+97 −73
Original line number Diff line number Diff line
@@ -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++;