From 0b576bb738f0201dcf5234172912ff1ce3ac0e30 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Mon, 15 Feb 2021 03:05:13 +0900 Subject: [PATCH] lib/iscsi: Factor out reading PDU payload operation from iscsi_read_pdu() This patch follows the last cleanup. Factor out reading PDU payload operation from iscsi_read_pdu() into a helper function iscsi_pdu_payload_read(). This reduces the nesting level, improves the readability, and make the following patches easier. Signed-off-by: Shuhei Matsumoto Change-Id: Ie5f51eedefe00f3b43a7b45dcf84be79f8df4e27 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6414 Reviewed-by: Ziye Yang Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Tested-by: SPDK CI Jenkins Community-CI: Mellanox Build Bot --- lib/iscsi/iscsi.c | 157 +++++++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 70 deletions(-) diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 4138ccb66..5481ef62f 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -4555,15 +4555,93 @@ iscsi_pdu_payload_handle(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pd return rc; } +/* Return zero if completed to read payload, positive number if still in progress, + * or negative number if any error. + */ +static int +iscsi_pdu_payload_read(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) +{ + struct spdk_mempool *pool; + uint32_t data_len; + uint32_t crc32c; + int rc; + + data_len = pdu->data_segment_len; + + if (pdu->data_buf == NULL) { + if (data_len <= iscsi_get_max_immediate_data_size()) { + pool = g_iscsi.pdu_immediate_data_pool; + pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(iscsi_get_max_immediate_data_size()); + } else if (data_len <= SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) { + pool = g_iscsi.pdu_data_out_pool; + pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); + } else { + SPDK_ERRLOG("Data(%d) > MaxSegment(%d)\n", + data_len, SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); + return -1; + } + pdu->mobj = spdk_mempool_get(pool); + if (pdu->mobj == NULL) { + return 1; + } + pdu->data_buf = pdu->mobj->buf; + pdu->data = pdu->mobj->buf; + pdu->data_from_mempool = true; + } + + /* copy the actual data into local buffer */ + if ((pdu->data_valid_bytes < data_len)) { + rc = iscsi_conn_read_data_segment(conn, pdu, data_len); + if (rc < 0) { + return rc; + } + + pdu->data_valid_bytes += rc; + if (pdu->data_valid_bytes < data_len) { + return 1; + } + } + + /* copy out the data digest */ + if (conn->data_digest && + pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) { + rc = iscsi_conn_read_data(conn, + ISCSI_DIGEST_LEN - pdu->ddigest_valid_bytes, + pdu->data_digest + pdu->ddigest_valid_bytes); + if (rc < 0) { + return rc; + } + + pdu->ddigest_valid_bytes += rc; + if (pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) { + return 1; + } + } + + /* All data for this PDU has now been read from the socket. */ + spdk_trace_record(TRACE_ISCSI_READ_PDU, conn->id, pdu->data_valid_bytes, + (uintptr_t)pdu, pdu->bhs.opcode); + + /* check data digest */ + if (conn->data_digest) { + crc32c = iscsi_pdu_calc_data_digest(pdu); + rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); + if (rc == 0) { + SPDK_ERRLOG("data digest error (%s)\n", conn->initiator_name); + return -1; + } + } + + return 0; +} + static int iscsi_read_pdu(struct spdk_iscsi_conn *conn) { enum iscsi_pdu_recv_state prev_state; struct spdk_iscsi_pdu *pdu; - struct spdk_mempool *pool; uint32_t crc32c; int ahs_len; - uint32_t data_len; int rc; do { @@ -4668,74 +4746,13 @@ iscsi_read_pdu(struct spdk_iscsi_conn *conn) conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_AWAIT_PDU_PAYLOAD; break; case ISCSI_PDU_RECV_STATE_AWAIT_PDU_PAYLOAD: - data_len = pdu->data_segment_len; - if (data_len != 0) { - if (pdu->data_buf == NULL) { - if (data_len <= iscsi_get_max_immediate_data_size()) { - pool = g_iscsi.pdu_immediate_data_pool; - pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(iscsi_get_max_immediate_data_size()); - } else if (data_len <= SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) { - pool = g_iscsi.pdu_data_out_pool; - pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); - } else { - SPDK_ERRLOG("Data(%d) > MaxSegment(%d)\n", - data_len, SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); - conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR; - break; - } - pdu->mobj = spdk_mempool_get(pool); - if (pdu->mobj == NULL) { - return 0; - } - pdu->data_buf = pdu->mobj->buf; - pdu->data = pdu->mobj->buf; - pdu->data_from_mempool = true; - } - - /* copy the actual data into local buffer */ - if ((pdu->data_valid_bytes < data_len)) { - rc = iscsi_conn_read_data_segment(conn, pdu, data_len); - if (rc < 0) { - conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR; - break; - } - - pdu->data_valid_bytes += rc; - if (pdu->data_valid_bytes < data_len) { - return 0; - } - } - - /* copy out the data digest */ - if (conn->data_digest && - pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) { - rc = iscsi_conn_read_data(conn, - ISCSI_DIGEST_LEN - pdu->ddigest_valid_bytes, - pdu->data_digest + pdu->ddigest_valid_bytes); - if (rc < 0) { - conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR; - break; - } - - pdu->ddigest_valid_bytes += rc; - if (pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) { - return 0; - } - } - - /* All data for this PDU has now been read from the socket. */ - spdk_trace_record(TRACE_ISCSI_READ_PDU, conn->id, pdu->data_valid_bytes, - (uintptr_t)pdu, pdu->bhs.opcode); - - /* check data digest */ - if (conn->data_digest) { - crc32c = iscsi_pdu_calc_data_digest(pdu); - rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); - if (rc == 0) { - SPDK_ERRLOG("data digest error (%s)\n", conn->initiator_name); - conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR; - break; - } + if (pdu->data_segment_len != 0) { + rc = iscsi_pdu_payload_read(conn, pdu); + if (rc > 0) { + return 0; + } else if (rc < 0) { + conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR; + break; } }