aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2009-11-11 17:34:31 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:35 -0500
commit4f704dc03297406ea5d53b85c4666c60f69000bf (patch)
treeee226b0502ab1b5ad5473615aab004dd2ba0a851 /drivers/scsi/libiscsi.c
parent24246de77503978cfcd7e76f06404e60e399992f (diff)
[SCSI] libiscsi: fix login/text checks in pdu injection code
For some reason we used to check for the the immediate bit set and the opcocde in many places instead of just masking the opcode. In the passthrough code this is a problem because userspace may or may not have set the immediate bit and it does not have to. This fixes up the opcode checks in the passthrough code, so we mask off the opcode then check against the iscsi proto definition like is done in other places. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 67d0f3fc8ac0..8c29480fc02b 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -577,12 +577,12 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
577 struct iscsi_session *session = conn->session; 577 struct iscsi_session *session = conn->session;
578 struct iscsi_hdr *hdr = task->hdr; 578 struct iscsi_hdr *hdr = task->hdr;
579 struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr; 579 struct iscsi_nopout *nop = (struct iscsi_nopout *)hdr;
580 uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
580 581
581 if (conn->session->state == ISCSI_STATE_LOGGING_OUT) 582 if (conn->session->state == ISCSI_STATE_LOGGING_OUT)
582 return -ENOTCONN; 583 return -ENOTCONN;
583 584
584 if (hdr->opcode != (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) && 585 if (opcode != ISCSI_OP_LOGIN && opcode != ISCSI_OP_TEXT)
585 hdr->opcode != (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
586 nop->exp_statsn = cpu_to_be32(conn->exp_statsn); 586 nop->exp_statsn = cpu_to_be32(conn->exp_statsn);
587 /* 587 /*
588 * pre-format CmdSN for outgoing PDU. 588 * pre-format CmdSN for outgoing PDU.
@@ -590,9 +590,12 @@ static int iscsi_prep_mgmt_task(struct iscsi_conn *conn,
590 nop->cmdsn = cpu_to_be32(session->cmdsn); 590 nop->cmdsn = cpu_to_be32(session->cmdsn);
591 if (hdr->itt != RESERVED_ITT) { 591 if (hdr->itt != RESERVED_ITT) {
592 /* 592 /*
593 * TODO: We always use immediate, so we never hit this. 593 * TODO: We always use immediate for normal session pdus.
594 * If we start to send tmfs or nops as non-immediate then 594 * If we start to send tmfs or nops as non-immediate then
595 * we should start checking the cmdsn numbers for mgmt tasks. 595 * we should start checking the cmdsn numbers for mgmt tasks.
596 *
597 * During discovery sessions iscsid sends TEXT as non immediate,
598 * but we always only send one PDU at a time.
596 */ 599 */
597 if (conn->c_stage == ISCSI_CONN_STARTED && 600 if (conn->c_stage == ISCSI_CONN_STARTED &&
598 !(hdr->opcode & ISCSI_OP_IMMEDIATE)) { 601 !(hdr->opcode & ISCSI_OP_IMMEDIATE)) {
@@ -620,22 +623,28 @@ __iscsi_conn_send_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
620{ 623{
621 struct iscsi_session *session = conn->session; 624 struct iscsi_session *session = conn->session;
622 struct iscsi_host *ihost = shost_priv(session->host); 625 struct iscsi_host *ihost = shost_priv(session->host);
626 uint8_t opcode = hdr->opcode & ISCSI_OPCODE_MASK;
623 struct iscsi_task *task; 627 struct iscsi_task *task;
624 itt_t itt; 628 itt_t itt;
625 629
626 if (session->state == ISCSI_STATE_TERMINATE) 630 if (session->state == ISCSI_STATE_TERMINATE)
627 return NULL; 631 return NULL;
628 632
629 if (hdr->opcode == (ISCSI_OP_LOGIN | ISCSI_OP_IMMEDIATE) || 633 if (opcode == ISCSI_OP_LOGIN || opcode == ISCSI_OP_TEXT) {
630 hdr->opcode == (ISCSI_OP_TEXT | ISCSI_OP_IMMEDIATE))
631 /* 634 /*
632 * Login and Text are sent serially, in 635 * Login and Text are sent serially, in
633 * request-followed-by-response sequence. 636 * request-followed-by-response sequence.
634 * Same task can be used. Same ITT must be used. 637 * Same task can be used. Same ITT must be used.
635 * Note that login_task is preallocated at conn_create(). 638 * Note that login_task is preallocated at conn_create().
636 */ 639 */
640 if (conn->login_task->state != ISCSI_TASK_FREE) {
641 iscsi_conn_printk(KERN_ERR, conn, "Login/Text in "
642 "progress. Cannot start new task.\n");
643 return NULL;
644 }
645
637 task = conn->login_task; 646 task = conn->login_task;
638 else { 647 } else {
639 if (session->state != ISCSI_STATE_LOGGED_IN) 648 if (session->state != ISCSI_STATE_LOGGED_IN)
640 return NULL; 649 return NULL;
641 650