]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/scsi/libiscsi.c
UBUNTU: Ubuntu-4.13.0-45.50
[mirror_ubuntu-artful-kernel.git] / drivers / scsi / libiscsi.c
index 42381adf076991d4e2fb4ed2a11e18162e93df25..f11c16500ff1cbe2bc1a1776d563c701ea8f3618 100644 (file)
@@ -1696,6 +1696,15 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc)
                 */
                switch (session->state) {
                case ISCSI_STATE_FAILED:
+                       /*
+                        * cmds should fail during shutdown, if the session
+                        * state is bad, allowing completion to happen
+                        */
+                       if (unlikely(system_state != SYSTEM_RUNNING)) {
+                               reason = FAILURE_SESSION_FAILED;
+                               sc->result = DID_NO_CONNECT << 16;
+                               break;
+                       }
                case ISCSI_STATE_IN_RECOVERY:
                        reason = FAILURE_SESSION_IN_RECOVERY;
                        sc->result = DID_IMM_RETRY << 16;
@@ -1980,6 +1989,19 @@ enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc)
        }
 
        if (session->state != ISCSI_STATE_LOGGED_IN) {
+               /*
+                * During shutdown, if session is prematurely disconnected,
+                * recovery won't happen and there will be hung cmds. Not
+                * handling cmds would trigger EH, also bad in this case.
+                * Instead, handle cmd, allow completion to happen and let
+                * upper layer to deal with the result.
+                */
+               if (unlikely(system_state != SYSTEM_RUNNING)) {
+                       sc->result = DID_NO_CONNECT << 16;
+                       ISCSI_DBG_EH(session, "sc on shutdown, handled\n");
+                       rc = BLK_EH_HANDLED;
+                       goto done;
+               }
                /*
                 * We are probably in the middle of iscsi recovery so let
                 * that complete and handle the error.
@@ -2084,7 +2106,7 @@ done:
                task->last_timeout = jiffies;
        spin_unlock(&session->frwd_lock);
        ISCSI_DBG_EH(session, "return %s\n", rc == BLK_EH_RESET_TIMER ?
-                    "timer reset" : "nh");
+                    "timer reset" : "shutdown or nh");
        return rc;
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_cmd_timed_out);