Commit 136c3fb4 authored by Shuhei Matsumoto's avatar Shuhei Matsumoto Committed by Changpeng Liu
Browse files

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: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446406


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarChangpeng Liu <changpeng.liu@intel.com>
Reviewed-by: default avatarZiye Yang <ziye.yang@intel.com>
parent 466ca6d4
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -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;
	}

+12 −3
Original line number Diff line number Diff line
@@ -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;
	}
}