Commit 247e4e6e authored by Changpeng Liu's avatar Changpeng Liu Committed by Konrad Sztyber
Browse files

lib/dif: set Reference Tag/Application Ingore Tag



For UNMAP and WRITE ZEROES, we should also set correct
values for Application Tag/Reference Tag, when reading
contents from the deallocated ranges, we will skip
checking the protection information based on DIF type.

Here, we use `SPDK_DIF_APPTAG_IGNORE` and `SPDK_DIF_REFTAG_IGNORE`
as the special values when creating DIF context, when the two
values are used for Application Tag and initialization Reference Tag,
we will fill the protection information fields with above
values based on check flags, then when doing verify with
above values in protection information fields, the checking
will be ignored.

Change-Id: I045fb3863cc6567f961905ce8bf57b90895c0e9c
Signed-off-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/20492


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
Reviewed-by: default avatarJim Harris <jim.harris@samsung.com>
Community-CI: Mellanox Build Bot
parent fc5be175
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -8,6 +8,18 @@
#include "spdk/stdinc.h"
#include "spdk/assert.h"

/**
 * Use `SPDK_DIF_APPTAG_IGNORE` and `SPDK_DIF_REFTAG_IGNORE`
 * as the special values when creating DIF context, when the two
 * values are used for Application Tag and Initialization Reference Tag,
 * DIF library will fill the protection information fields with above
 * values, based on the specification, when doing verify with
 * above values in protection information field, the checking
 * will be ignored.
 */
#define SPDK_DIF_REFTAG_IGNORE		0xFFFFFFFF
#define SPDK_DIF_APPTAG_IGNORE		0xFFFF

#define SPDK_DIF_FLAGS_REFTAG_CHECK	(1U << 26)
#define SPDK_DIF_FLAGS_APPTAG_CHECK	(1U << 27)
#define SPDK_DIF_FLAGS_GUARD_CHECK	(1U << 28)
+12 −29
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@
#include "spdk/log.h"
#include "spdk/util.h"

#define APPTAG_IGNORE 0xFFFF
#define REFTAG_MASK_16 0x00000000FFFFFFFF
#define REFTAG_MASK_32 0xFFFFFFFFFFFFFFFF
#define REFTAG_MASK_64 0x0000FFFFFFFFFFFF
@@ -185,28 +184,6 @@ _dif_sgl_copy(struct _dif_sgl *to, struct _dif_sgl *from)
	memcpy(to, from, sizeof(struct _dif_sgl));
}

static bool
_dif_type_is_valid(enum spdk_dif_type dif_type, uint32_t dif_flags)
{
	switch (dif_type) {
	case SPDK_DIF_TYPE1:
	case SPDK_DIF_TYPE2:
	case SPDK_DIF_DISABLE:
		break;
	case SPDK_DIF_TYPE3:
		if (dif_flags & SPDK_DIF_FLAGS_REFTAG_CHECK) {
			SPDK_ERRLOG("Reference Tag should not be checked for Type 3\n");
			return false;
		}
		break;
	default:
		SPDK_ERRLOG("Unknown DIF Type: %d\n", dif_type);
		return false;
	}

	return true;
}

static bool
_dif_is_disabled(enum spdk_dif_type dif_type)
{
@@ -384,7 +361,7 @@ _dif_get_apptag(struct spdk_dif *dif, enum spdk_dif_pi_format dif_pi_format)
static inline bool
_dif_apptag_ignore(struct spdk_dif *dif, enum spdk_dif_pi_format dif_pi_format)
{
	return _dif_get_apptag(dif, dif_pi_format) == APPTAG_IGNORE;
	return _dif_get_apptag(dif, dif_pi_format) == SPDK_DIF_APPTAG_IGNORE;
}

static inline uint8_t
@@ -525,11 +502,6 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz
		data_block_size = block_size;
	}

	if (!_dif_type_is_valid(dif_type, dif_flags)) {
		SPDK_ERRLOG("DIF type is invalid.\n");
		return -EINVAL;
	}

	ctx->block_size = block_size;
	ctx->md_size = md_size;
	ctx->md_interleave = md_interleave;
@@ -598,6 +570,17 @@ _dif_generate(void *_dif, uint64_t guard, uint32_t offset_blocks,
			ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset;
		}

		/* Overwrite reference tag if initialization reference tag is SPDK_DIF_REFTAG_IGNORE */
		if (ctx->init_ref_tag == SPDK_DIF_REFTAG_IGNORE) {
			if (ctx->dif_pi_format == SPDK_DIF_PI_FORMAT_16) {
				ref_tag = REFTAG_MASK_16;
			} else if (ctx->dif_pi_format == SPDK_DIF_PI_FORMAT_32) {
				ref_tag = REFTAG_MASK_32;
			} else {
				ref_tag = REFTAG_MASK_64;
			}
		}

		_dif_set_reftag(dif, ref_tag, ctx->dif_pi_format);
	}
}
+53 −0
Original line number Diff line number Diff line
@@ -4032,6 +4032,58 @@ dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test(void)
	_iov_free_buf(&md_iov);
}

static void
dif_generate_and_verify_unmap_test(void)
{
	struct iovec iov;
	struct spdk_dif_ctx ctx = {};
	int rc;
	struct spdk_dif_ctx_init_ext_opts dif_opts;
	uint32_t dif_flags;
	struct spdk_dif *dif;

	_iov_alloc_buf(&iov, 4096 + 128);

	dif_opts.size = SPDK_SIZEOF(&dif_opts, dif_pi_format);
	dif_opts.dif_pi_format = SPDK_DIF_PI_FORMAT_16;
	dif = (struct spdk_dif *)(iov.iov_base + 4096);

	/* Case 1 for TYPE1 */
	memset(iov.iov_base, 0, 4096 + 128);
	dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | SPDK_DIF_FLAGS_REFTAG_CHECK;
	rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE1, dif_flags,
			       0x100, 0xFFFF, SPDK_DIF_APPTAG_IGNORE, 0, 0, &dif_opts);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_generate(&iov, 1, 1, &ctx);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_verify(&iov, 1, 1, &ctx, NULL);
	CU_ASSERT(rc == 0);

	CU_ASSERT(_dif_get_apptag(dif, ctx.dif_pi_format) == SPDK_DIF_APPTAG_IGNORE);
	CU_ASSERT(_dif_get_reftag(dif, ctx.dif_pi_format) == 0x100);

	/* Case 2 for TYPE3 */
	memset(iov.iov_base, 0, 4096 + 128);

	dif_flags = SPDK_DIF_FLAGS_GUARD_CHECK | SPDK_DIF_FLAGS_APPTAG_CHECK | SPDK_DIF_FLAGS_REFTAG_CHECK;
	rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, true, SPDK_DIF_TYPE3, dif_flags,
			       SPDK_DIF_REFTAG_IGNORE, 0xFFFF, SPDK_DIF_APPTAG_IGNORE, 0, 0, &dif_opts);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_generate(&iov, 1, 1, &ctx);
	CU_ASSERT(rc == 0);

	rc = spdk_dif_verify(&iov, 1, 1, &ctx, NULL);
	CU_ASSERT(rc == 0);

	CU_ASSERT(_dif_get_apptag(dif, ctx.dif_pi_format) == SPDK_DIF_APPTAG_IGNORE);
	CU_ASSERT(_dif_get_reftag(dif, ctx.dif_pi_format) == REFTAG_MASK_16);

	_iov_free_buf(&iov);
}

int
main(int argc, char **argv)
{
@@ -4120,6 +4172,7 @@ main(int argc, char **argv)
	CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_remap);
	CU_ADD_TEST(suite, dix_sec_512_md_8_prchk_7_multi_iovs_complex_splits_remap_pi_16_test);
	CU_ADD_TEST(suite, dix_sec_4096_md_128_prchk_7_multi_iovs_complex_splits_remap_test);
	CU_ADD_TEST(suite, dif_generate_and_verify_unmap_test);


	num_failures = spdk_ut_run_tests(argc, argv, NULL);