From 3de09f8eceb8fec1e7b4ff9fdf89c2a924747c52 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Mon, 15 Feb 2021 14:54:22 +0900 Subject: [PATCH] lib/iscsi: Support data split case for CRC32C computation Add crc32c to struct spdk_iscsi_pdu and initialize it by SPDK_CRC32C_INITIAL, and then use it as the initial value of _iscsi_pdu_calc_data_digest(). Separate finalization of crc32c into _iscsi_pdu_finalize_data_digest(). Move the definition of related macro constants from iscsi.c to iscsi.h. iscsi_pdu_calc_data_digest() is used for read too. So setting pdu->valid_data_bytes before calling iscsi_pdu_calc_data_digest() for read. Data split will be supported only if DIF is disabled, and hence DIF case is not changed. Signed-off-by: Shuhei Matsumoto Change-Id: I9d24f605fd0d452782e17695b613cd2f63d2e42f Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6421 Tested-by: SPDK CI Jenkins Community-CI: Mellanox Build Bot Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu --- lib/iscsi/iscsi.c | 33 +++++++++++++++++++++------------ lib/iscsi/iscsi.h | 4 ++++ lib/iscsi/iscsi_subsystem.c | 1 + 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 4e309a3cd..525992b7e 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -59,9 +59,6 @@ #define MAX_TMPBUF 1024 -#define SPDK_CRC32C_INITIAL 0xffffffffUL -#define SPDK_CRC32C_XOR 0xffffffffUL - #ifdef __FreeBSD__ #define HAVE_SRANDOMDEV 1 #define HAVE_ARC4RANDOM 1 @@ -311,27 +308,31 @@ iscsi_pdu_calc_header_digest(struct spdk_iscsi_pdu *pdu) return crc32c; } -uint32_t -iscsi_pdu_calc_data_digest(struct spdk_iscsi_pdu *pdu) +static void +_iscsi_pdu_calc_data_digest(struct spdk_iscsi_pdu *pdu) { - uint32_t data_len = DGET24(pdu->bhs.data_segment_len); - uint32_t crc32c; - uint32_t mod; struct iovec iov; uint32_t num_blocks; - crc32c = SPDK_CRC32C_INITIAL; if (spdk_likely(!pdu->dif_insert_or_strip)) { - crc32c = spdk_crc32c_update(pdu->data, data_len, crc32c); + pdu->crc32c = spdk_crc32c_update(pdu->data, pdu->data_valid_bytes, + pdu->crc32c); } else { iov.iov_base = pdu->data; iov.iov_len = pdu->data_buf_len; num_blocks = pdu->data_buf_len / pdu->dif_ctx.block_size; - spdk_dif_update_crc32c(&iov, 1, num_blocks, &crc32c, &pdu->dif_ctx); + spdk_dif_update_crc32c(&iov, 1, num_blocks, &pdu->crc32c, &pdu->dif_ctx); } +} - mod = data_len % ISCSI_ALIGNMENT; +static uint32_t +_iscsi_pdu_finalize_data_digest(struct spdk_iscsi_pdu *pdu) +{ + uint32_t crc32c = pdu->crc32c; + uint32_t mod; + + mod = pdu->data_valid_bytes % ISCSI_ALIGNMENT; if (mod != 0) { uint32_t pad_length = ISCSI_ALIGNMENT - mod; uint8_t pad[3] = {0, 0, 0}; @@ -345,6 +346,13 @@ iscsi_pdu_calc_data_digest(struct spdk_iscsi_pdu *pdu) return crc32c; } +uint32_t +iscsi_pdu_calc_data_digest(struct spdk_iscsi_pdu *pdu) +{ + _iscsi_pdu_calc_data_digest(pdu); + return _iscsi_pdu_finalize_data_digest(pdu); +} + static int iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, @@ -2919,6 +2927,7 @@ iscsi_send_datain(struct spdk_iscsi_conn *conn, rsph = (struct iscsi_bhs_data_in *)&rsp_pdu->bhs; rsp_pdu->data = task->scsi.iovs[0].iov_base + offset; rsp_pdu->data_buf_len = task->scsi.iovs[0].iov_len - offset; + rsp_pdu->data_valid_bytes = len; rsp_pdu->data_from_mempool = true; task_tag = task->tag; diff --git a/lib/iscsi/iscsi.h b/lib/iscsi/iscsi.h index 8c0f22066..88a2e9f21 100644 --- a/lib/iscsi/iscsi.h +++ b/lib/iscsi/iscsi.h @@ -155,6 +155,9 @@ struct spdk_mobj { */ #define SPDK_ISCSI_MAX_SGL_DESCRIPTORS (5) +#define SPDK_CRC32C_INITIAL 0xffffffffUL +#define SPDK_CRC32C_XOR 0xffffffffUL + typedef void (*iscsi_conn_xfer_complete_cb)(void *cb_arg); struct spdk_iscsi_pdu { @@ -176,6 +179,7 @@ struct spdk_iscsi_pdu { uint32_t cmd_sn; uint32_t writev_offset; uint32_t data_buf_len; + uint32_t crc32c; bool dif_insert_or_strip; struct spdk_dif_ctx dif_ctx; struct spdk_iscsi_conn *conn; diff --git a/lib/iscsi/iscsi_subsystem.c b/lib/iscsi/iscsi_subsystem.c index bf1311abc..dbec73424 100644 --- a/lib/iscsi/iscsi_subsystem.c +++ b/lib/iscsi/iscsi_subsystem.c @@ -260,6 +260,7 @@ struct spdk_iscsi_pdu *iscsi_get_pdu(struct spdk_iscsi_conn *conn) memset(pdu, 0, offsetof(struct spdk_iscsi_pdu, ahs)); pdu->ref = 1; pdu->conn = conn; + pdu->crc32c = SPDK_CRC32C_INITIAL; return pdu; }