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 <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I9d24f605fd0d452782e17695b613cd2f63d2e42f
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6421
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Mellanox Build Bot
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Shuhei Matsumoto 2021-02-15 14:54:22 +09:00 committed by Tomasz Zawadzki
parent acdeb53f4b
commit 3de09f8ece
3 changed files with 26 additions and 12 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}