diff --git a/examples/nvme/fio_plugin/fio_plugin.c b/examples/nvme/fio_plugin/fio_plugin.c index 2c87cd913..08a7d1aec 100644 --- a/examples/nvme/fio_plugin/fio_plugin.c +++ b/examples/nvme/fio_plugin/fio_plugin.c @@ -575,7 +575,7 @@ fio_extended_lba_setup_pi(struct spdk_fio_qpair *fio_qpair, struct io_u *io_u) rc = spdk_dif_ctx_init(&fio_req->dif_ctx, extended_lba_size, md_size, true, fio_qpair->md_start, (enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns), - fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0); + fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0, 0); if (rc != 0) { fprintf(stderr, "Initialization of DIF context failed\n"); return rc; @@ -609,7 +609,7 @@ fio_separate_md_setup_pi(struct spdk_fio_qpair *fio_qpair, struct io_u *io_u) rc = spdk_dif_ctx_init(&fio_req->dif_ctx, block_size, md_size, false, fio_qpair->md_start, (enum spdk_dif_type)spdk_nvme_ns_get_pi_type(ns), - fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0); + fio_qpair->io_flags, lba, g_spdk_apptag_mask, g_spdk_apptag, 0, 0); if (rc != 0) { fprintf(stderr, "Initialization of DIF context failed\n"); return rc; diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index 25313f3b2..f6fe258c6 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -485,7 +485,7 @@ nvme_submit_io(struct perf_task *task, struct ns_worker_ctx *ns_ctx, rc = spdk_dif_ctx_init(&task->dif_ctx, entry->block_size, entry->md_size, entry->md_interleave, entry->pi_loc, (enum spdk_dif_type)entry->pi_type, entry->io_flags, - lba, 0xFFFF, (uint16_t)entry->io_size_blocks, 0); + lba, 0xFFFF, (uint16_t)entry->io_size_blocks, 0, 0); if (rc != 0) { fprintf(stderr, "Initialization of DIF context failed\n"); exit(1); diff --git a/include/spdk/dif.h b/include/spdk/dif.h index 0e7173956..20dd17e3d 100644 --- a/include/spdk/dif.h +++ b/include/spdk/dif.h @@ -92,6 +92,12 @@ struct spdk_dif_ctx { /* Application tag mask */ uint16_t apptag_mask; + /* Byte offset from the start of the whole data buffer. */ + uint32_t data_offset; + + /* Offset to initial reference tag */ + uint32_t ref_tag_offset; + /* Seed value for guard computation */ uint16_t guard_seed; }; @@ -127,6 +133,7 @@ struct spdk_dif_error { * starting block address. * \param apptag_mask Application tag mask. * \param app_tag Application tag. + * \param data_offset Byte offset from the start of the whole data buffer. * \param guard_seed Seed value for guard computation. * * \return 0 on success and negated errno otherwise. @@ -134,7 +141,7 @@ struct spdk_dif_error { int spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, - uint16_t guard_seed); + uint32_t data_offset, uint16_t guard_seed); /** * Generate DIF for extended LBA payload. diff --git a/include/spdk/scsi.h b/include/spdk/scsi.h index 1e922709d..e9b5d4ff7 100644 --- a/include/spdk/scsi.h +++ b/include/spdk/scsi.h @@ -527,7 +527,7 @@ void spdk_scsi_lun_free_io_channel(struct spdk_scsi_lun_desc *desc); * * \param lun Logical unit. * \param cdb SCSI CDB. - * \param offset Offset in the payload. + * \param offset Byte offset in the payload. * \param dif_ctx Output parameter which will contain initialized DIF context. * * \return true on success or false otherwise. diff --git a/lib/bdev/nvme/bdev_nvme.c b/lib/bdev/nvme/bdev_nvme.c index f6e9fe060..989b5e2e0 100644 --- a/lib/bdev/nvme/bdev_nvme.c +++ b/lib/bdev/nvme/bdev_nvme.c @@ -1631,7 +1631,7 @@ bdev_nvme_verify_pi_error(struct spdk_bdev_io *bdev_io) rc = spdk_dif_ctx_init(&dif_ctx, bdev->blocklen, bdev->md_len, bdev->md_interleave, bdev->dif_is_head_of_md, bdev->dif_type, bdev->dif_check_flags, - bdev_io->u.bdev.offset_blocks, 0, 0, 0); + bdev_io->u.bdev.offset_blocks, 0, 0, 0, 0); if (rc != 0) { SPDK_ERRLOG("Initialization of DIF context failed\n"); return; diff --git a/lib/scsi/scsi_bdev.c b/lib/scsi/scsi_bdev.c index 90b401b6f..535a759e4 100644 --- a/lib/scsi/scsi_bdev.c +++ b/lib/scsi/scsi_bdev.c @@ -2164,7 +2164,7 @@ spdk_scsi_bdev_get_dif_ctx(struct spdk_bdev *bdev, uint8_t *cdb, uint32_t offset spdk_bdev_is_dif_head_of_md(bdev), spdk_bdev_get_dif_type(bdev), dif_check_flags, - ref_tag, 0, 0, 0); + ref_tag, 0, 0, 0, 0); return (rc == 0) ? true : false; } diff --git a/lib/util/dif.c b/lib/util/dif.c index 372ca58a2..5f56f363e 100644 --- a/lib/util/dif.c +++ b/lib/util/dif.c @@ -200,8 +200,10 @@ int spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, - uint16_t guard_seed) + uint32_t data_offset, uint16_t guard_seed) { + uint32_t data_block_size; + if (md_size < sizeof(struct spdk_dif)) { SPDK_ERRLOG("Metadata size is smaller than DIF size.\n"); return -EINVAL; @@ -212,11 +214,13 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz SPDK_ERRLOG("Block size is smaller than DIF size.\n"); return -EINVAL; } + data_block_size = block_size - md_size; } else { if (block_size == 0 || (block_size % 512) != 0) { SPDK_ERRLOG("Zero block size is not allowed\n"); return -EINVAL; } + data_block_size = block_size; } if (!_dif_type_is_valid(dif_type, dif_flags)) { @@ -232,6 +236,8 @@ spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_siz ctx->init_ref_tag = init_ref_tag; ctx->apptag_mask = apptag_mask; ctx->app_tag = app_tag; + ctx->data_offset = data_offset; + ctx->ref_tag_offset = data_offset / data_block_size; ctx->guard_seed = guard_seed; return 0; @@ -258,9 +264,9 @@ _dif_generate(void *_dif, uint16_t guard, uint32_t offset_blocks, * remains the same as the initial reference tag. */ if (ctx->dif_type != SPDK_DIF_TYPE3) { - ref_tag = ctx->init_ref_tag + offset_blocks; + ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset + offset_blocks; } else { - ref_tag = ctx->init_ref_tag; + ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset; } to_be32(&dif->ref_tag, ref_tag); @@ -420,9 +426,9 @@ _dif_verify(void *_dif, uint16_t guard, uint32_t offset_blocks, * remains the same as the initial reference tag. */ if (ctx->dif_type != SPDK_DIF_TYPE3) { - ref_tag = ctx->init_ref_tag + offset_blocks; + ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset + offset_blocks; } else { - ref_tag = ctx->init_ref_tag; + ref_tag = ctx->init_ref_tag + ctx->ref_tag_offset; } if (ctx->dif_flags & SPDK_DIF_FLAGS_GUARD_CHECK) { diff --git a/test/bdev/bdevperf/bdevperf.c b/test/bdev/bdevperf/bdevperf.c index 15fce7f17..4217edb33 100644 --- a/test/bdev/bdevperf/bdevperf.c +++ b/test/bdev/bdevperf/bdevperf.c @@ -562,7 +562,7 @@ bdevperf_generate_dif(struct bdevperf_task *task) spdk_bdev_is_dif_head_of_md(bdev), spdk_bdev_get_dif_type(bdev), target->dif_check_flags, - task->offset_blocks, 0, 0, 0); + task->offset_blocks, 0, 0, 0, 0); if (rc != 0) { fprintf(stderr, "Initialization of DIF context failed\n"); return rc; diff --git a/test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut.c b/test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut.c index 70b229ffc..347905470 100644 --- a/test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut.c +++ b/test/unit/lib/scsi/scsi_bdev.c/scsi_bdev_ut.c @@ -272,7 +272,7 @@ int spdk_dif_ctx_init(struct spdk_dif_ctx *ctx, uint32_t block_size, uint32_t md_size, bool md_interleave, bool dif_loc, enum spdk_dif_type dif_type, uint32_t dif_flags, uint32_t init_ref_tag, uint16_t apptag_mask, uint16_t app_tag, - uint16_t guard_seed) + uint32_t data_offset, uint16_t guard_seed) { ctx->init_ref_tag = init_ref_tag; return 0; diff --git a/test/unit/lib/util/dif.c/dif_ut.c b/test/unit/lib/util/dif.c/dif_ut.c index 8caa27f71..4455f63a4 100644 --- a/test/unit/lib/util/dif.c/dif_ut.c +++ b/test/unit/lib/util/dif.c/dif_ut.c @@ -294,7 +294,7 @@ dif_sec_512_md_0_error_test(void) int rc; /* Metadata size is 0. */ - rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0); + rc = spdk_dif_ctx_init(&ctx, 512, 0, true, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0); CU_ASSERT(rc != 0); } @@ -315,7 +315,7 @@ dif_guard_seed_test(void) dif = (struct spdk_dif *)(iov.iov_base + 512); rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, - SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0); + SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, 0); CU_ASSERT(rc == 0); rc = spdk_dif_generate(&iov, 1, 1, &ctx); @@ -329,7 +329,7 @@ dif_guard_seed_test(void) CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, - SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, GUARD_SEED); + SPDK_DIF_FLAGS_GUARD_CHECK, 0, 0, 0, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dif_generate(&iov, 1, 1, &ctx); @@ -358,7 +358,7 @@ dif_generate_and_verify(struct iovec *iovs, int iovcnt, CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, - init_ref_tag, apptag_mask, app_tag, GUARD_SEED); + init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); @@ -663,7 +663,7 @@ _dif_inject_error_and_verify(struct iovec *iovs, int iovcnt, CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, - SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, GUARD_SEED); + SPDK_DIF_TYPE1, dif_flags, 88, 0xFFFF, 0x88, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dif_generate(iovs, iovcnt, num_blocks, &ctx); @@ -821,7 +821,7 @@ dif_copy_gen_and_verify(struct iovec *iovs, int iovcnt, struct iovec *bounce_iov CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, dif_type, dif_flags, - init_ref_tag, apptag_mask, app_tag, GUARD_SEED); + init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx); @@ -992,7 +992,7 @@ _dif_copy_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec * CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, block_size, md_size, true, dif_loc, SPDK_DIF_TYPE1, dif_flags, - 88, 0xFFFF, 0x88, GUARD_SEED); + 88, 0xFFFF, 0x88, 0, GUARD_SEED); SPDK_CU_ASSERT_FATAL(rc == 0); rc = spdk_dif_generate_copy(iovs, iovcnt, bounce_iov, num_blocks, &ctx); @@ -1097,7 +1097,7 @@ dix_sec_512_md_0_error(void) struct spdk_dif_ctx ctx; int rc; - rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0); + rc = spdk_dif_ctx_init(&ctx, 512, 0, false, false, SPDK_DIF_TYPE1, 0, 0, 0, 0, 0, 0); CU_ASSERT(rc != 0); } @@ -1114,7 +1114,7 @@ dix_generate_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_iov, CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, dif_type, dif_flags, - init_ref_tag, apptag_mask, app_tag, GUARD_SEED); + init_ref_tag, apptag_mask, app_tag, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); @@ -1280,7 +1280,7 @@ _dix_inject_error_and_verify(struct iovec *iovs, int iovcnt, struct iovec *md_io CU_ASSERT(rc == 0); rc = spdk_dif_ctx_init(&ctx, block_size, md_size, false, dif_loc, SPDK_DIF_TYPE1, dif_flags, - 88, 0xFFFF, 0x88, GUARD_SEED); + 88, 0xFFFF, 0x88, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dix_generate(iovs, iovcnt, md_iov, num_blocks, &ctx); @@ -1399,7 +1399,7 @@ set_md_interleave_iovs_test(void) SPDK_DIF_FLAGS_REFTAG_CHECK; rc = spdk_dif_ctx_init(&ctx, 4096 + 128, 128, true, false, SPDK_DIF_TYPE1, - dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED); + dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); CU_ASSERT(rc == 0); /* The first data buffer: @@ -1522,7 +1522,7 @@ set_md_interleave_iovs_split_test(void) SPDK_DIF_FLAGS_REFTAG_CHECK; rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, - dif_check_flags, 22, 0xFFFF, 0x22, GUARD_SEED); + dif_check_flags, 22, 0xFFFF, 0x22, 0, GUARD_SEED); CU_ASSERT(rc == 0); /* The first SGL data buffer: @@ -1676,7 +1676,7 @@ dif_generate_stream_test(void) SPDK_DIF_FLAGS_REFTAG_CHECK; rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, dif_flags, - 22, 0xFFFF, 0x22, GUARD_SEED); + 22, 0xFFFF, 0x22, 0, GUARD_SEED); CU_ASSERT(rc == 0); rc = spdk_dif_generate_stream(&iov, 1, 0, 511, &ctx); @@ -1724,7 +1724,7 @@ update_crc32c_test(void) SPDK_DIF_FLAGS_REFTAG_CHECK; rc = spdk_dif_ctx_init(&ctx, 512 + 8, 8, true, false, SPDK_DIF_TYPE1, - dif_flags, 0, 0, 0, 0); + dif_flags, 0, 0, 0, 0, 0); CU_ASSERT(rc == 0); /* data[0][255:0] */