From b689bf62fbf13deeb3eeeebed0f0f507b236e857 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Thu, 3 Oct 2019 10:18:57 +0900 Subject: [PATCH] lib/iscsi: Move spdk_iscsi_read_pdu() down in the file The subsequent patches will merge spdk_iscsi_read_pdu(), spdk_iscsi_execute(), and iscsi_conn_handle_incoming_pdus() into a single function by introducing state machine. Current ordering will create unnecessary function declaration. Hence move spdk_iscsi_read_pdu() down to the next to spdk_iscsi_execute() to avoid it. Signed-off-by: Shuhei Matsumoto Change-Id: I289ebcfc20d90753545ab9500b64fd93ca9dfb6d Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/470284 Reviewed-by: Jim Harris Reviewed-by: Changpeng Liu Tested-by: SPDK CI Jenkins --- lib/iscsi/iscsi.c | 356 +++++++++++++++++++++++----------------------- 1 file changed, 178 insertions(+), 178 deletions(-) diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 3049349e9..8e02ac170 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -460,184 +460,6 @@ iscsi_conn_read_data_segment(struct spdk_iscsi_conn *conn, } } -int -spdk_iscsi_read_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu **_pdu) -{ - struct spdk_iscsi_pdu *pdu; - struct spdk_mempool *pool; - uint32_t crc32c; - int ahs_len; - int data_len; - int rc; - - if (conn->pdu_in_progress == NULL) { - conn->pdu_in_progress = spdk_get_pdu(); - if (conn->pdu_in_progress == NULL) { - return SPDK_ISCSI_CONNECTION_FATAL; - } - } - - pdu = conn->pdu_in_progress; - - if (pdu->bhs_valid_bytes < ISCSI_BHS_LEN) { - rc = spdk_iscsi_conn_read_data(conn, - ISCSI_BHS_LEN - pdu->bhs_valid_bytes, - (uint8_t *)&pdu->bhs + pdu->bhs_valid_bytes); - if (rc < 0) { - goto error; - } - pdu->bhs_valid_bytes += rc; - if (pdu->bhs_valid_bytes < ISCSI_BHS_LEN) { - return 0; - } - } - - data_len = ISCSI_ALIGN(DGET24(pdu->bhs.data_segment_len)); - - /* AHS */ - ahs_len = pdu->bhs.total_ahs_len * 4; - assert(ahs_len <= ISCSI_AHS_LEN); - if (pdu->ahs_valid_bytes < ahs_len) { - rc = spdk_iscsi_conn_read_data(conn, - ahs_len - pdu->ahs_valid_bytes, - pdu->ahs + pdu->ahs_valid_bytes); - if (rc < 0) { - goto error; - } - - pdu->ahs_valid_bytes += rc; - if (pdu->ahs_valid_bytes < ahs_len) { - return 0; - } - } - - /* Header Digest */ - if (conn->header_digest && - pdu->hdigest_valid_bytes < ISCSI_DIGEST_LEN) { - rc = spdk_iscsi_conn_read_data(conn, - ISCSI_DIGEST_LEN - pdu->hdigest_valid_bytes, - pdu->header_digest + pdu->hdigest_valid_bytes); - if (rc < 0) { - goto error; - } - - pdu->hdigest_valid_bytes += rc; - if (pdu->hdigest_valid_bytes < ISCSI_DIGEST_LEN) { - return 0; - } - } - - /* copy the actual data into local buffer */ - if (pdu->data_valid_bytes < data_len) { - if (pdu->data_buf == NULL) { - if (data_len <= spdk_get_max_immediate_data_size()) { - pool = g_spdk_iscsi.pdu_immediate_data_pool; - pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(spdk_get_max_immediate_data_size()); - } else if (data_len <= SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) { - pool = g_spdk_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); - rc = SPDK_ISCSI_CONNECTION_FATAL; - goto error; - } - pdu->mobj = spdk_mempool_get(pool); - if (pdu->mobj == NULL) { - return 0; - } - pdu->data_buf = pdu->mobj->buf; - - if (spdk_unlikely(spdk_iscsi_get_dif_ctx(conn, pdu, &pdu->dif_ctx))) { - pdu->dif_insert_or_strip = true; - } - } - - rc = iscsi_conn_read_data_segment(conn, pdu, data_len); - if (rc < 0) { - goto error; - } - - pdu->data_valid_bytes += rc; - if (pdu->data_valid_bytes < data_len) { - return 0; - } - } - - /* copy out the data digest */ - if (conn->data_digest && data_len != 0 && - pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) { - rc = spdk_iscsi_conn_read_data(conn, - ISCSI_DIGEST_LEN - pdu->ddigest_valid_bytes, - pdu->data_digest + pdu->ddigest_valid_bytes); - if (rc < 0) { - goto error; - } - - 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. */ - conn->pdu_in_progress = NULL; - - spdk_trace_record(TRACE_ISCSI_READ_PDU, conn->id, pdu->data_valid_bytes, - (uintptr_t)pdu, pdu->bhs.opcode); - - /* Data Segment */ - if (data_len != 0) { - if (!iscsi_check_data_segment_length(conn, pdu, data_len)) { - rc = iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); - /* - * If spdk_iscsi_reject() was not able to reject the PDU, - * treat it as a fatal connection error. Otherwise, - * return SUCCESS here so that the caller will continue - * to attempt to read PDUs. - */ - if (rc == 0) { - spdk_put_pdu(pdu); - return 0; - } else { - goto error; - } - } - - pdu->data = pdu->data_buf; - pdu->data_from_mempool = true; - pdu->data_segment_len = data_len; - } - - /* check digest */ - if (conn->header_digest) { - crc32c = spdk_iscsi_pdu_calc_header_digest(pdu); - rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); - if (rc == 0) { - SPDK_ERRLOG("header digest error (%s)\n", conn->initiator_name); - rc = SPDK_ISCSI_CONNECTION_FATAL; - goto error; - } - } - if (conn->data_digest && data_len != 0) { - crc32c = spdk_iscsi_pdu_calc_data_digest(pdu); - rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); - if (rc == 0) { - rc = SPDK_ISCSI_CONNECTION_FATAL; - SPDK_ERRLOG("data digest error (%s)\n", conn->initiator_name); - goto error; - } - } - - *_pdu = pdu; - return 1; - -error: - spdk_put_pdu(pdu); - conn->pdu_in_progress = NULL; - return rc; -} - struct _iscsi_sgl { struct iovec *iov; int iovcnt; @@ -4806,6 +4628,184 @@ spdk_iscsi_execute(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) return 0; } +int +spdk_iscsi_read_pdu(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu **_pdu) +{ + struct spdk_iscsi_pdu *pdu; + struct spdk_mempool *pool; + uint32_t crc32c; + int ahs_len; + int data_len; + int rc; + + if (conn->pdu_in_progress == NULL) { + conn->pdu_in_progress = spdk_get_pdu(); + if (conn->pdu_in_progress == NULL) { + return SPDK_ISCSI_CONNECTION_FATAL; + } + } + + pdu = conn->pdu_in_progress; + + if (pdu->bhs_valid_bytes < ISCSI_BHS_LEN) { + rc = spdk_iscsi_conn_read_data(conn, + ISCSI_BHS_LEN - pdu->bhs_valid_bytes, + (uint8_t *)&pdu->bhs + pdu->bhs_valid_bytes); + if (rc < 0) { + goto error; + } + pdu->bhs_valid_bytes += rc; + if (pdu->bhs_valid_bytes < ISCSI_BHS_LEN) { + return 0; + } + } + + data_len = ISCSI_ALIGN(DGET24(pdu->bhs.data_segment_len)); + + /* AHS */ + ahs_len = pdu->bhs.total_ahs_len * 4; + assert(ahs_len <= ISCSI_AHS_LEN); + if (pdu->ahs_valid_bytes < ahs_len) { + rc = spdk_iscsi_conn_read_data(conn, + ahs_len - pdu->ahs_valid_bytes, + pdu->ahs + pdu->ahs_valid_bytes); + if (rc < 0) { + goto error; + } + + pdu->ahs_valid_bytes += rc; + if (pdu->ahs_valid_bytes < ahs_len) { + return 0; + } + } + + /* Header Digest */ + if (conn->header_digest && + pdu->hdigest_valid_bytes < ISCSI_DIGEST_LEN) { + rc = spdk_iscsi_conn_read_data(conn, + ISCSI_DIGEST_LEN - pdu->hdigest_valid_bytes, + pdu->header_digest + pdu->hdigest_valid_bytes); + if (rc < 0) { + goto error; + } + + pdu->hdigest_valid_bytes += rc; + if (pdu->hdigest_valid_bytes < ISCSI_DIGEST_LEN) { + return 0; + } + } + + /* copy the actual data into local buffer */ + if (pdu->data_valid_bytes < data_len) { + if (pdu->data_buf == NULL) { + if (data_len <= spdk_get_max_immediate_data_size()) { + pool = g_spdk_iscsi.pdu_immediate_data_pool; + pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(spdk_get_max_immediate_data_size()); + } else if (data_len <= SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) { + pool = g_spdk_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); + rc = SPDK_ISCSI_CONNECTION_FATAL; + goto error; + } + pdu->mobj = spdk_mempool_get(pool); + if (pdu->mobj == NULL) { + return 0; + } + pdu->data_buf = pdu->mobj->buf; + + if (spdk_unlikely(spdk_iscsi_get_dif_ctx(conn, pdu, &pdu->dif_ctx))) { + pdu->dif_insert_or_strip = true; + } + } + + rc = iscsi_conn_read_data_segment(conn, pdu, data_len); + if (rc < 0) { + goto error; + } + + pdu->data_valid_bytes += rc; + if (pdu->data_valid_bytes < data_len) { + return 0; + } + } + + /* copy out the data digest */ + if (conn->data_digest && data_len != 0 && + pdu->ddigest_valid_bytes < ISCSI_DIGEST_LEN) { + rc = spdk_iscsi_conn_read_data(conn, + ISCSI_DIGEST_LEN - pdu->ddigest_valid_bytes, + pdu->data_digest + pdu->ddigest_valid_bytes); + if (rc < 0) { + goto error; + } + + 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. */ + conn->pdu_in_progress = NULL; + + spdk_trace_record(TRACE_ISCSI_READ_PDU, conn->id, pdu->data_valid_bytes, + (uintptr_t)pdu, pdu->bhs.opcode); + + /* Data Segment */ + if (data_len != 0) { + if (!iscsi_check_data_segment_length(conn, pdu, data_len)) { + rc = iscsi_reject(conn, pdu, ISCSI_REASON_PROTOCOL_ERROR); + /* + * If spdk_iscsi_reject() was not able to reject the PDU, + * treat it as a fatal connection error. Otherwise, + * return SUCCESS here so that the caller will continue + * to attempt to read PDUs. + */ + if (rc == 0) { + spdk_put_pdu(pdu); + return 0; + } else { + goto error; + } + } + + pdu->data = pdu->data_buf; + pdu->data_from_mempool = true; + pdu->data_segment_len = data_len; + } + + /* check digest */ + if (conn->header_digest) { + crc32c = spdk_iscsi_pdu_calc_header_digest(pdu); + rc = MATCH_DIGEST_WORD(pdu->header_digest, crc32c); + if (rc == 0) { + SPDK_ERRLOG("header digest error (%s)\n", conn->initiator_name); + rc = SPDK_ISCSI_CONNECTION_FATAL; + goto error; + } + } + if (conn->data_digest && data_len != 0) { + crc32c = spdk_iscsi_pdu_calc_data_digest(pdu); + rc = MATCH_DIGEST_WORD(pdu->data_digest, crc32c); + if (rc == 0) { + rc = SPDK_ISCSI_CONNECTION_FATAL; + SPDK_ERRLOG("data digest error (%s)\n", conn->initiator_name); + goto error; + } + } + + *_pdu = pdu; + return 1; + +error: + spdk_put_pdu(pdu); + conn->pdu_in_progress = NULL; + return rc; +} + bool spdk_iscsi_get_dif_ctx(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu, struct spdk_dif_ctx *dif_ctx)