diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 8af08fce4..9b5267147 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -377,12 +377,6 @@ _iscsi_conn_free(struct spdk_iscsi_conn *conn) spdk_iscsi_param_free(conn->params); - /* - * Each connection pre-allocates its next PDU - make sure these get - * freed here. - */ - spdk_put_pdu(conn->pdu_in_progress); - free_conn(conn); } @@ -675,6 +669,10 @@ _iscsi_conn_check_pending_tasks(void *arg) void spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) { + struct spdk_iscsi_pdu *pdu; + struct spdk_iscsi_task *task; + int opcode; + /* If a connection is already in exited status, just return */ if (conn->state >= ISCSI_CONN_STATE_EXITED) { return; @@ -682,6 +680,32 @@ spdk_iscsi_conn_destruct(struct spdk_iscsi_conn *conn) conn->state = ISCSI_CONN_STATE_EXITED; + /* + * Each connection pre-allocates its next PDU - make sure these get + * freed here. + */ + pdu = conn->pdu_in_progress; + if (pdu) { + /* remove the task left in the PDU too. */ + task = pdu->task; + if (task) { + opcode = pdu->bhs.opcode; + switch (opcode) { + case ISCSI_OP_SCSI: + case ISCSI_OP_SCSI_DATAOUT: + spdk_scsi_task_process_abort(&task->scsi); + spdk_iscsi_task_cpl(&task->scsi); + break; + default: + SPDK_ERRLOG("unexpected opcode %x\n", opcode); + spdk_iscsi_task_put(task); + break; + } + } + spdk_put_pdu(pdu); + conn->pdu_in_progress = NULL; + } + if (conn->sess != NULL && conn->pending_task_cnt > 0) { iscsi_conn_cleanup_backend(conn); } diff --git a/lib/iscsi/iscsi.c b/lib/iscsi/iscsi.c index c23382272..d8305ac37 100644 --- a/lib/iscsi/iscsi.c +++ b/lib/iscsi/iscsi.c @@ -4970,8 +4970,6 @@ iscsi_read_pdu(struct spdk_iscsi_conn *conn) } break; case ISCSI_PDU_RECV_STATE_ERROR: - spdk_put_pdu(pdu); - conn->pdu_in_progress = NULL; return SPDK_ISCSI_CONNECTION_FATAL; default: assert(false);