LU Reset TMF can take quite some time to abort all pending
commands. Any other TMF submitted at that time will autmatically
fail. However, there is no reason to not allow another
TMF once we received the response as the only shared resource
here is the complete callback.

Signed-off-by: Hannes Reinecke <h...@suse.de>
---
 drivers/scsi/libiscsi.c    |   15 ++++++++++-----
 include/scsi/iscsi_proto.h |    2 ++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index fc10544..07a714d 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1929,6 +1929,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
        conn = session->leadconn;
        conn->eh_abort_cnt++;
        age = session->age;
+       hdr = &conn->tmhdr;
 
        task = (struct iscsi_task *)sc->SCp.ptr;
        ISCSI_DBG_EH(session, "aborting [sc %p itt 0x%x]\n",
@@ -1945,12 +1946,14 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
                goto success;
        }
 
-       /* only have one tmf outstanding at a time */
-       if (conn->tmf_state != TMF_INITIAL)
+       /* only have one tmf running at a time */
+       if (conn->tmf_state == TMF_QUEUED)
+               goto failed;
+       /* LUN Reset overrides ABORT TASK */
+       if (ISCSI_TM_FUNC_VALUE(hdr) == ISCSI_TM_FUNC_LOGICAL_UNIT_RESET)
                goto failed;
        conn->tmf_state = TMF_QUEUED;
 
-       hdr = &conn->tmhdr;
        iscsi_prep_abort_task_pdu(task, hdr);
 
        if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) {
@@ -2000,6 +2003,7 @@ success:
 success_unlocked:
        ISCSI_DBG_EH(session, "abort success [sc %p itt 0x%x]\n",
                     sc, task->itt);
+       memset(hdr, 0, sizeof(*hdr));
        mutex_unlock(&session->eh_mutex);
        return SUCCESS;
 
@@ -2046,8 +2050,8 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
                goto unlock;
        conn = session->leadconn;
 
-       /* only have one tmf outstanding at a time */
-       if (conn->tmf_state != TMF_INITIAL)
+       /* only have one tmf running at a time */
+       if (conn->tmf_state == TMF_QUEUED)
                goto unlock;
        conn->tmf_state = TMF_QUEUED;
 
@@ -2080,6 +2084,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
        spin_lock_bh(&session->lock);
        fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
        conn->tmf_state = TMF_INITIAL;
+       memset(hdr, 0, sizeof(*hdr));
        spin_unlock_bh(&session->lock);
 
        iscsi_start_tx(conn);
diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h
index f2a2c11..dd0a52c 100644
--- a/include/scsi/iscsi_proto.h
+++ b/include/scsi/iscsi_proto.h
@@ -279,6 +279,8 @@ struct iscsi_tm {
 #define ISCSI_TM_FUNC_TARGET_COLD_RESET                7
 #define ISCSI_TM_FUNC_TASK_REASSIGN            8
 
+#define ISCSI_TM_FUNC_VALUE(hdr) ((hdr)->flags & ISCSI_FLAG_TM_FUNC_MASK)
+
 /* SCSI Task Management Response Header */
 struct iscsi_tm_rsp {
        uint8_t opcode;
-- 
1.6.0.2


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To post to this group, send email to open-iscsi@googlegroups.com
To unsubscribe from this group, send email to 
open-iscsi+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/open-iscsi
-~----------~----~----~----~------~----~------~--~---

Reply via email to