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 <shuhei.matsumoto.xt@hitachi.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/446406 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Changpeng Liu <changpeng.liu@intel.com> Reviewed-by: Ziye Yang <ziye.yang@intel.com>
This commit is contained in:
parent
466ca6d494
commit
136c3fb461
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user