diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2006-10-16 18:09:42 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-10-25 15:14:05 -0700 |
commit | b5072ea0910e5c8c79b8313e0ef70ca763983dbf (patch) | |
tree | 518228880851f5067553543bca314fa96436168d | |
parent | 5831c737f724aa6a655a908d202221f079f30036 (diff) | |
download | kernel_samsung_espresso10-b5072ea0910e5c8c79b8313e0ef70ca763983dbf.zip kernel_samsung_espresso10-b5072ea0910e5c8c79b8313e0ef70ca763983dbf.tar.gz kernel_samsung_espresso10-b5072ea0910e5c8c79b8313e0ef70ca763983dbf.tar.bz2 |
[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 <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/libiscsi.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index f5a9560..2865ebd 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; } |