From b5072ea0910e5c8c79b8313e0ef70ca763983dbf Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 16 Oct 2006 18:09:42 -0400 Subject: [PATCH] [SCSI] libiscsi: fix logout pdu processing According to the iscsi RFC, we cannot send other requests if we have sent a logout pdu. This patch enforces this requirement by blocking the session and suspending the send thread. Userspace decides if we restart the connection or if we just free everything. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- drivers/scsi/libiscsi.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index f5a9560b357f..2865ebd557ef 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -578,6 +578,27 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } 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 @@ -623,7 +644,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) 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 */ @@ -638,7 +659,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) 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; }