diff --git a/CHANGELOG.md b/CHANGELOG.md index b24ca2948..7a43d32e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ A new uuid API `spdk_uuid_copy` was added to make a copy of the source uuid. +An new parameter `init_crc` representing the initial CRC value was added to +`spdk_crc16_t10dif`. The parameter can be used to calculate a CRC value spanning +multiple separate buffers. + ### nvme admin_timeout_ms was added to NVMe controller initialization options, users diff --git a/examples/nvme/fio_plugin/fio_plugin.c b/examples/nvme/fio_plugin/fio_plugin.c index 042531cba..4ce9ba022 100644 --- a/examples/nvme/fio_plugin/fio_plugin.c +++ b/examples/nvme/fio_plugin/fio_plugin.c @@ -564,7 +564,7 @@ fio_extended_lba_setup_pi(struct spdk_fio_qpair *fio_qpair, struct io_u *io_u) if (io_u->ddir == DDIR_WRITE) { if (fio_qpair->io_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { /* CRC buffer should not include PI */ - crc16 = spdk_crc16_t10dif(io_u->buf + extended_lba_size * i, + crc16 = spdk_crc16_t10dif(0, io_u->buf + extended_lba_size * i, extended_lba_size - 8); to_be16(&pi->guard, crc16); } @@ -601,7 +601,7 @@ fio_extended_lba_verify_pi(struct spdk_fio_qpair *fio_qpair, struct io_u *io_u) if (fio_qpair->io_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { /* CRC buffer should not include last 8 bytes of PI */ - crc16 = spdk_crc16_t10dif(io_u->buf + extended_lba_size * i, + crc16 = spdk_crc16_t10dif(0, io_u->buf + extended_lba_size * i, extended_lba_size - 8); to_be16(&guard, crc16); if (pi->guard != guard) { diff --git a/examples/nvme/perf/perf.c b/examples/nvme/perf/perf.c index 187a95cde..bfbb6a301 100644 --- a/examples/nvme/perf/perf.c +++ b/examples/nvme/perf/perf.c @@ -541,7 +541,7 @@ task_extended_lba_setup_pi(struct ns_entry *entry, struct perf_task *task, uint6 if (is_write) { if (entry->io_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { /* CRC buffer should not include PI */ - crc16 = spdk_crc16_t10dif(task->buf + (sector_size + md_size) * i, + crc16 = spdk_crc16_t10dif(0, task->buf + (sector_size + md_size) * i, sector_size + md_size - 8); to_be16(&pi->guard, crc16); } @@ -585,7 +585,7 @@ task_extended_lba_pi_verify(struct ns_entry *entry, struct perf_task *task, if (entry->io_flags & SPDK_NVME_IO_FLAGS_PRCHK_GUARD) { /* CRC buffer should not include last 8 bytes of PI */ - crc16 = spdk_crc16_t10dif(task->buf + (sector_size + md_size) * i, + crc16 = spdk_crc16_t10dif(0, task->buf + (sector_size + md_size) * i, sector_size + md_size - 8); to_be16(&guard, crc16); if (pi->guard != guard) { diff --git a/include/spdk/crc16.h b/include/spdk/crc16.h index ad79a41d8..382d9d62e 100644 --- a/include/spdk/crc16.h +++ b/include/spdk/crc16.h @@ -53,12 +53,12 @@ extern "C" { /** * Calculate T10-DIF CRC-16 checksum. * + * \param init_crc Initial CRC-16 value. * \param buf Data buffer to checksum. * \param len Length of buf in bytes. * \return CRC-16 value. */ -uint16_t spdk_crc16_t10dif(const void *buf, size_t len); - +uint16_t spdk_crc16_t10dif(uint16_t init_crc, const void *buf, size_t len); #ifdef __cplusplus } #endif diff --git a/lib/util/crc16.c b/lib/util/crc16.c index 491c90589..5e19e6937 100644 --- a/lib/util/crc16.c +++ b/lib/util/crc16.c @@ -34,14 +34,16 @@ #include "spdk/crc16.h" uint16_t -spdk_crc16_t10dif(const void *buf, size_t len) +spdk_crc16_t10dif(uint16_t init_crc, const void *buf, size_t len) { - uint32_t j, rem = 0; + uint32_t j, rem; const uint8_t *data = (const uint8_t *)buf; size_t i; uint16_t poly = SPDK_T10DIF_CRC16_POLYNOMIAL; + rem = init_crc; + for (i = 0; i < len; i++) { rem = rem ^ (data[i] << 8); for (j = 0; j < 8; j++) { diff --git a/test/nvme/e2edp/nvme_dp.c b/test/nvme/e2edp/nvme_dp.c index eaf2bd323..3666eff24 100644 --- a/test/nvme/e2edp/nvme_dp.c +++ b/test/nvme/e2edp/nvme_dp.c @@ -154,10 +154,10 @@ static uint32_t dp_guard_check_extended_lba_test(struct spdk_nvme_ns *ns, struct ns_data_buffer_reset(ns, req, DATA_PATTERN); pi = (struct spdk_nvme_protection_info *)(req->contig + sector_size + md_size - 8); /* big-endian for guard */ - to_be16(&pi->guard, spdk_crc16_t10dif(req->contig, sector_size)); + to_be16(&pi->guard, spdk_crc16_t10dif(0, req->contig, sector_size)); pi = (struct spdk_nvme_protection_info *)(req->contig + (sector_size + md_size) * 2 - 8); - to_be16(&pi->guard, spdk_crc16_t10dif(req->contig + sector_size + md_size, sector_size)); + to_be16(&pi->guard, spdk_crc16_t10dif(0, req->contig + sector_size + md_size, sector_size)); *io_flags = SPDK_NVME_IO_FLAGS_PRCHK_GUARD; diff --git a/test/unit/lib/util/crc16.c/crc16_ut.c b/test/unit/lib/util/crc16.c/crc16_ut.c index 8b05e900c..360299c6a 100644 --- a/test/unit/lib/util/crc16.c/crc16_ut.c +++ b/test/unit/lib/util/crc16.c/crc16_ut.c @@ -43,7 +43,19 @@ test_crc16_t10dif(void) uint16_t crc; char buf[] = "123456789"; - crc = spdk_crc16_t10dif(buf, strlen(buf)); + crc = spdk_crc16_t10dif(0, buf, strlen(buf)); + CU_ASSERT(crc == 0xd0db); +} + +static void +test_crc16_t10dif_seed(void) +{ + uint16_t crc = 0; + char buf1[] = "1234"; + char buf2[] = "56789"; + + crc = spdk_crc16_t10dif(crc, buf1, strlen(buf1)); + crc = spdk_crc16_t10dif(crc, buf2, strlen(buf2)); CU_ASSERT(crc == 0xd0db); } @@ -64,7 +76,8 @@ main(int argc, char **argv) } if ( - CU_add_test(suite, "test_crc16_t10dif", test_crc16_t10dif) == NULL) { + CU_add_test(suite, "test_crc16_t10dif", test_crc16_t10dif) == NULL || + CU_add_test(suite, "test_crc16_t10dif_seed", test_crc16_t10dif_seed) == NULL) { CU_cleanup_registry(); return CU_get_error(); }