lib/iscsi: Check if data comes really after processing logout request
When the PDU receive handler processes the header of the logout request PDU, conn->is_logged_out is set to true. However, if conn->is_logged_out is true, conn->pdu_recv_state is set to ERROR before the PDU receive handler completes processing the logout request PDU. Then if conn->pdu_recv_state is ERROR, conn->state is set to EXITING after returning from the PDU receive handler. Response PDUs are sent asynchronously now and may not be sent even after returning from the PDU receive handler. On the other hand, outside the PDU receive handler, the current connection is closed if conn->state is EXITING. Hence logout response PDU may not be sent to the initiator. For the case that the initiator logs out and then reconnects when receiving asynchronous logout request, missing logout response is critical because initiator waits until receiving logout request and gets timeout. This patch moves the check if PDU comes after logout to the place just after getting a PDU header. At the new location, data segment of the PDU is not received yet. But logout request PDU does not have data segment and initiator will not send additional PDU after sending logout request PDU, and by this patch, iSCSI target will continue to stop receiving any new PDU after processing logout request. Furthermore, even if there is any remaining data in the kernel buffer, the kernel will discard or flush it when closing the socket. Fixes issue #1571 Signed-off-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Change-Id: I9554f4d54f3db80bf86abd6bffe81bac8c234531 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/3928 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ziye Yang <ziye.yang@intel.com>
This commit is contained in:
parent
59ad0a04fa
commit
438fa38e4a
@ -4582,6 +4582,17 @@ iscsi_read_pdu(struct spdk_iscsi_conn *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* conn->is_logged_out must be checked after completing to process
|
||||
* logout request, i.e., before processing PDU header in this state
|
||||
* machine, otherwise logout response may not be sent to initiator
|
||||
* and initiator may get logout timeout.
|
||||
*/
|
||||
if (spdk_unlikely(conn->is_logged_out)) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "pdu received after logout\n");
|
||||
conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
pdu->data_segment_len = ISCSI_ALIGN(DGET24(pdu->bhs.data_segment_len));
|
||||
|
||||
/* AHS */
|
||||
@ -4709,12 +4720,6 @@ iscsi_read_pdu(struct spdk_iscsi_conn *conn)
|
||||
}
|
||||
}
|
||||
|
||||
if (conn->is_logged_out) {
|
||||
SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "pdu received after logout\n");
|
||||
conn->pdu_recv_state = ISCSI_PDU_RECV_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pdu->is_rejected) {
|
||||
rc = iscsi_pdu_payload_handle(conn, pdu);
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user