From 136c3fb46184b4ba90adb5bf7017cce3212d5d52 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 7 Mar 2019 12:49:49 +0900 Subject: [PATCH] iscsi: Generate and verify DIF to metadata space in read or write I/O Generate and insert DIF for write I/O by stream fashion in spdk_iscsi_read_pdu(). Verify DIF for read I/O in spdk_iscsi_conn_write_pdu(). Verification can be done in spdk_iscsi_build_iovs(), but how many writes to socket is not known beforehand, and same range may be verified multiple times. So verify DIF before starting to write to socket. Change-Id: I860637758164b7d518c38fe92356562cbbe3d8f8 Signed-off-by: Shuhei Matsumoto Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446406 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu Reviewed-by: Ziye Yang --- lib/iscsi/conn.c | 28 ++++++++++++++++++++++++++++ lib/iscsi/iscsi.c | 15 ++++++++++++--- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 2cf8f23f6..1518f2ee5 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -1297,12 +1297,40 @@ spdk_iscsi_conn_flush_pdus(void *_conn) return 1; } +static int +spdk_iscsi_dif_verify(struct spdk_iscsi_pdu *pdu, struct spdk_dif_ctx *dif_ctx) +{ + struct iovec iov; + struct spdk_dif_error err_blk = {}; + uint32_t num_blocks; + int rc; + + iov.iov_base = pdu->data; + iov.iov_len = pdu->data_buf_len; + num_blocks = pdu->data_buf_len / dif_ctx->block_size; + + rc = spdk_dif_verify(&iov, 1, num_blocks, dif_ctx, &err_blk); + if (rc != 0) { + SPDK_ERRLOG("DIF error detected. type=%d, offset=%" PRIu32 "\n", + err_blk.err_type, err_blk.err_offset); + } + + return rc; +} + void spdk_iscsi_conn_write_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) { uint32_t crc32c; + int rc; if (spdk_unlikely(spdk_iscsi_get_dif_ctx(conn, pdu, &pdu->dif_ctx))) { + rc = spdk_iscsi_dif_verify(pdu, &pdu->dif_ctx); + if (rc != 0) { + spdk_iscsi_conn_free_pdu(conn, pdu); + conn->state = ISCSI_CONN_STATE_EXITING; + return; + } pdu->dif_insert_or_strip = true; } diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 6a13370ae..1c6dd571a 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -392,7 +392,7 @@ spdk_iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn, { struct spdk_dif_ctx dif_ctx; struct iovec iovs[32]; - int rc; + int rc, _rc; if (spdk_likely(!spdk_iscsi_get_dif_ctx(conn, pdu, &dif_ctx))) { return spdk_iscsi_conn_read_data(conn, @@ -405,11 +405,20 @@ spdk_iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn, pdu->data_valid_bytes, segment_len, NULL, &dif_ctx); if (rc > 0) { - return spdk_iscsi_conn_readv_data(conn, iovs, rc); + rc = spdk_iscsi_conn_readv_data(conn, iovs, rc); + if (rc > 0) { + _rc = spdk_dif_generate_stream(pdu->data_buf, pdu->data_buf_len, + pdu->data_valid_bytes, rc, + &dif_ctx); + if (_rc != 0) { + SPDK_ERRLOG("DIF generate failed\n"); + rc = _rc; + } + } } else { SPDK_ERRLOG("Setup iovs for interleaved metadata failed\n"); - return rc; } + return rc; } }