From e536464357cd6353ee2d6b7c0ba6295e53324db7 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Tue, 5 Oct 2021 23:10:45 +0900 Subject: [PATCH] iscsi: Fix the case that incoming data is split into multiple packets We had not considered a case that incoming data to the second data buffer was split into multiple TCP packets when merging incoming data up to 64KB. We do not change the unit test because we already have data check and it is very hard to include partial read into the data check. However, it is very usual that incoming data is split into multple TCP packets. The feature to merge incoming data up to 64KB will be actually enabled in the following patches. So we rely on the I/O test to verify this fix. Signed-off-by: Shuhei Matsumoto Change-Id: I50d702d6c118bc16f0767845136e14414ccdf813 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/9736 Community-CI: Broadcom CI Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Ben Walker --- lib/iscsi/iscsi.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index 5eedbc53e..afecab9e6 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -4644,24 +4644,26 @@ iscsi_pdu_payload_read(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu) pdu->data = mobj->buf; pdu->data_from_mempool = true; } else if (mobj->data_len == SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH) { - /* The first data buffer ran out. Allocate the second data buffer and - * continue reading the data segment. - */ - assert(pdu->mobj[1] == NULL); - assert(pdu->data_from_mempool == true); - assert(!pdu->dif_insert_or_strip); - - if (conn->data_digest) { - iscsi_pdu_calc_partial_data_digest(pdu); - } - mobj = iscsi_datapool_get(g_iscsi.pdu_data_out_pool); + mobj = pdu->mobj[1]; if (mobj == NULL) { - return 1; + /* The first data buffer just ran out. Allocate the second data buffer and + * continue reading the data segment. + */ + assert(pdu->data_from_mempool == true); + assert(!pdu->dif_insert_or_strip); + + if (conn->data_digest) { + iscsi_pdu_calc_partial_data_digest(pdu); + } + mobj = iscsi_datapool_get(g_iscsi.pdu_data_out_pool); + if (mobj == NULL) { + return 1; + } + pdu->mobj[1] = mobj; + pdu->data = mobj->buf; + pdu->data_offset = pdu->data_valid_bytes; + pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); } - pdu->mobj[1] = mobj; - pdu->data = mobj->buf; - pdu->data_offset = pdu->data_valid_bytes; - pdu->data_buf_len = SPDK_BDEV_BUF_SIZE_WITH_MD(SPDK_ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH); } /* copy the actual data into local buffer */