break;
case ISCSI_OP_ASYNC_EVENT:
conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
- /* we need sth like iscsi_async_event_rsp() */
- rc = ISCSI_ERR_BAD_OPCODE;
+ if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen))
+ rc = ISCSI_ERR_CONN_FAILED;
break;
default:
rc = ISCSI_ERR_BAD_OPCODE;
}
EXPORT_SYMBOL_GPL(iscsi_conn_failure);
+static int iscsi_xmit_imm_task(struct iscsi_conn *conn)
+{
+ struct iscsi_hdr *hdr = conn->mtask->hdr;
+ int rc, was_logout = 0;
+
+ if ((hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT) {
+ conn->session->state = ISCSI_STATE_IN_RECOVERY;
+ iscsi_block_session(session_to_cls(conn->session));
+ was_logout = 1;
+ }
+ rc = conn->session->tt->xmit_mgmt_task(conn, conn->mtask);
+ if (rc)
+ return rc;
+
+ if (was_logout) {
+ set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
+ return -ENODATA;
+ }
+ return 0;
+}
+
/**
* iscsi_data_xmit - xmit any command into the scheduled connection
* @conn: iscsi connection
conn->ctask = NULL;
}
if (conn->mtask) {
- rc = tt->xmit_mgmt_task(conn, conn->mtask);
+ rc = iscsi_xmit_imm_task(conn);
if (rc)
goto again;
/* done with this in-progress mtask */
list_add_tail(&conn->mtask->running,
&conn->mgmt_run_list);
spin_unlock_bh(&conn->session->lock);
- rc = tt->xmit_mgmt_task(conn, conn->mtask);
+ rc = iscsi_xmit_imm_task(conn);
if (rc)
goto again;
}
spin_unlock_bh(&conn->session->lock);
rc = tt->xmit_cmd_task(conn, conn->ctask);
- if (rc)
- goto again;
spin_lock_bh(&conn->session->lock);
__iscsi_put_ctask(conn->ctask);