diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 183 |
1 files changed, 149 insertions, 34 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index da7b67d30d9a..801c7cf54d2e 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
@@ -404,11 +404,6 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_task *task, | |||
404 | conn->session->queued_cmdsn--; | 404 | conn->session->queued_cmdsn--; |
405 | else | 405 | else |
406 | conn->session->tt->cleanup_task(conn, task); | 406 | conn->session->tt->cleanup_task(conn, task); |
407 | /* | ||
408 | * Check if cleanup_task dropped the lock and the command completed, | ||
409 | */ | ||
410 | if (!task->sc) | ||
411 | return; | ||
412 | 407 | ||
413 | sc->result = err; | 408 | sc->result = err; |
414 | if (!scsi_bidi_cmnd(sc)) | 409 | if (!scsi_bidi_cmnd(sc)) |
@@ -633,6 +628,40 @@ out: | |||
633 | __iscsi_put_task(task); | 628 | __iscsi_put_task(task); |
634 | } | 629 | } |
635 | 630 | ||
631 | /** | ||
632 | * iscsi_data_in_rsp - SCSI Data-In Response processing | ||
633 | * @conn: iscsi connection | ||
634 | * @hdr: iscsi pdu | ||
635 | * @task: scsi command task | ||
636 | **/ | ||
637 | static void | ||
638 | iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | ||
639 | struct iscsi_task *task) | ||
640 | { | ||
641 | struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr; | ||
642 | struct scsi_cmnd *sc = task->sc; | ||
643 | |||
644 | if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS)) | ||
645 | return; | ||
646 | |||
647 | sc->result = (DID_OK << 16) | rhdr->cmd_status; | ||
648 | conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; | ||
649 | if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW | | ||
650 | ISCSI_FLAG_DATA_OVERFLOW)) { | ||
651 | int res_count = be32_to_cpu(rhdr->residual_count); | ||
652 | |||
653 | if (res_count > 0 && | ||
654 | (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW || | ||
655 | res_count <= scsi_in(sc)->length)) | ||
656 | scsi_in(sc)->resid = res_count; | ||
657 | else | ||
658 | sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; | ||
659 | } | ||
660 | |||
661 | conn->scsirsp_pdus_cnt++; | ||
662 | __iscsi_put_task(task); | ||
663 | } | ||
664 | |||
636 | static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) | 665 | static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) |
637 | { | 666 | { |
638 | struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; | 667 | struct iscsi_tm_rsp *tmf = (struct iscsi_tm_rsp *)hdr; |
@@ -818,12 +847,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, | |||
818 | iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); | 847 | iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); |
819 | break; | 848 | break; |
820 | case ISCSI_OP_SCSI_DATA_IN: | 849 | case ISCSI_OP_SCSI_DATA_IN: |
821 | if (hdr->flags & ISCSI_FLAG_DATA_STATUS) { | 850 | iscsi_data_in_rsp(conn, hdr, task); |
822 | conn->scsirsp_pdus_cnt++; | ||
823 | iscsi_update_cmdsn(session, | ||
824 | (struct iscsi_nopin*) hdr); | ||
825 | __iscsi_put_task(task); | ||
826 | } | ||
827 | break; | 851 | break; |
828 | case ISCSI_OP_LOGOUT_RSP: | 852 | case ISCSI_OP_LOGOUT_RSP: |
829 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); | 853 | iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); |
@@ -954,6 +978,38 @@ struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) | |||
954 | } | 978 | } |
955 | EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); | 979 | EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); |
956 | 980 | ||
981 | void iscsi_session_failure(struct iscsi_cls_session *cls_session, | ||
982 | enum iscsi_err err) | ||
983 | { | ||
984 | struct iscsi_session *session = cls_session->dd_data; | ||
985 | struct iscsi_conn *conn; | ||
986 | struct device *dev; | ||
987 | unsigned long flags; | ||
988 | |||
989 | spin_lock_irqsave(&session->lock, flags); | ||
990 | conn = session->leadconn; | ||
991 | if (session->state == ISCSI_STATE_TERMINATE || !conn) { | ||
992 | spin_unlock_irqrestore(&session->lock, flags); | ||
993 | return; | ||
994 | } | ||
995 | |||
996 | dev = get_device(&conn->cls_conn->dev); | ||
997 | spin_unlock_irqrestore(&session->lock, flags); | ||
998 | if (!dev) | ||
999 | return; | ||
1000 | /* | ||
1001 | * if the host is being removed bypass the connection | ||
1002 | * recovery initialization because we are going to kill | ||
1003 | * the session. | ||
1004 | */ | ||
1005 | if (err == ISCSI_ERR_INVALID_HOST) | ||
1006 | iscsi_conn_error_event(conn->cls_conn, err); | ||
1007 | else | ||
1008 | iscsi_conn_failure(conn, err); | ||
1009 | put_device(dev); | ||
1010 | } | ||
1011 | EXPORT_SYMBOL_GPL(iscsi_session_failure); | ||
1012 | |||
957 | void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | 1013 | void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) |
958 | { | 1014 | { |
959 | struct iscsi_session *session = conn->session; | 1015 | struct iscsi_session *session = conn->session; |
@@ -968,9 +1024,10 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) | |||
968 | if (conn->stop_stage == 0) | 1024 | if (conn->stop_stage == 0) |
969 | session->state = ISCSI_STATE_FAILED; | 1025 | session->state = ISCSI_STATE_FAILED; |
970 | spin_unlock_irqrestore(&session->lock, flags); | 1026 | spin_unlock_irqrestore(&session->lock, flags); |
1027 | |||
971 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); | 1028 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx); |
972 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); | 1029 | set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_rx); |
973 | iscsi_conn_error(conn->cls_conn, err); | 1030 | iscsi_conn_error_event(conn->cls_conn, err); |
974 | } | 1031 | } |
975 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); | 1032 | EXPORT_SYMBOL_GPL(iscsi_conn_failure); |
976 | 1033 | ||
@@ -1194,15 +1251,13 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
1194 | switch (session->state) { | 1251 | switch (session->state) { |
1195 | case ISCSI_STATE_IN_RECOVERY: | 1252 | case ISCSI_STATE_IN_RECOVERY: |
1196 | reason = FAILURE_SESSION_IN_RECOVERY; | 1253 | reason = FAILURE_SESSION_IN_RECOVERY; |
1197 | sc->result = DID_IMM_RETRY << 16; | 1254 | goto reject; |
1198 | break; | ||
1199 | case ISCSI_STATE_LOGGING_OUT: | 1255 | case ISCSI_STATE_LOGGING_OUT: |
1200 | reason = FAILURE_SESSION_LOGGING_OUT; | 1256 | reason = FAILURE_SESSION_LOGGING_OUT; |
1201 | sc->result = DID_IMM_RETRY << 16; | 1257 | goto reject; |
1202 | break; | ||
1203 | case ISCSI_STATE_RECOVERY_FAILED: | 1258 | case ISCSI_STATE_RECOVERY_FAILED: |
1204 | reason = FAILURE_SESSION_RECOVERY_TIMEOUT; | 1259 | reason = FAILURE_SESSION_RECOVERY_TIMEOUT; |
1205 | sc->result = DID_NO_CONNECT << 16; | 1260 | sc->result = DID_TRANSPORT_FAILFAST << 16; |
1206 | break; | 1261 | break; |
1207 | case ISCSI_STATE_TERMINATE: | 1262 | case ISCSI_STATE_TERMINATE: |
1208 | reason = FAILURE_SESSION_TERMINATE; | 1263 | reason = FAILURE_SESSION_TERMINATE; |
@@ -1267,7 +1322,7 @@ reject: | |||
1267 | spin_unlock(&session->lock); | 1322 | spin_unlock(&session->lock); |
1268 | debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); | 1323 | debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason); |
1269 | spin_lock(host->host_lock); | 1324 | spin_lock(host->host_lock); |
1270 | return SCSI_MLQUEUE_HOST_BUSY; | 1325 | return SCSI_MLQUEUE_TARGET_BUSY; |
1271 | 1326 | ||
1272 | fault: | 1327 | fault: |
1273 | spin_unlock(&session->lock); | 1328 | spin_unlock(&session->lock); |
@@ -1307,7 +1362,7 @@ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session) | |||
1307 | } | 1362 | } |
1308 | EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); | 1363 | EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); |
1309 | 1364 | ||
1310 | int iscsi_eh_host_reset(struct scsi_cmnd *sc) | 1365 | int iscsi_eh_target_reset(struct scsi_cmnd *sc) |
1311 | { | 1366 | { |
1312 | struct iscsi_cls_session *cls_session; | 1367 | struct iscsi_cls_session *cls_session; |
1313 | struct iscsi_session *session; | 1368 | struct iscsi_session *session; |
@@ -1321,7 +1376,7 @@ int iscsi_eh_host_reset(struct scsi_cmnd *sc) | |||
1321 | spin_lock_bh(&session->lock); | 1376 | spin_lock_bh(&session->lock); |
1322 | if (session->state == ISCSI_STATE_TERMINATE) { | 1377 | if (session->state == ISCSI_STATE_TERMINATE) { |
1323 | failed: | 1378 | failed: |
1324 | debug_scsi("failing host reset: session terminated " | 1379 | debug_scsi("failing target reset: session terminated " |
1325 | "[CID %d age %d]\n", conn->id, session->age); | 1380 | "[CID %d age %d]\n", conn->id, session->age); |
1326 | spin_unlock_bh(&session->lock); | 1381 | spin_unlock_bh(&session->lock); |
1327 | mutex_unlock(&session->eh_mutex); | 1382 | mutex_unlock(&session->eh_mutex); |
@@ -1336,7 +1391,7 @@ failed: | |||
1336 | */ | 1391 | */ |
1337 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); | 1392 | iscsi_conn_failure(conn, ISCSI_ERR_CONN_FAILED); |
1338 | 1393 | ||
1339 | debug_scsi("iscsi_eh_host_reset wait for relogin\n"); | 1394 | debug_scsi("iscsi_eh_target_reset wait for relogin\n"); |
1340 | wait_event_interruptible(conn->ehwait, | 1395 | wait_event_interruptible(conn->ehwait, |
1341 | session->state == ISCSI_STATE_TERMINATE || | 1396 | session->state == ISCSI_STATE_TERMINATE || |
1342 | session->state == ISCSI_STATE_LOGGED_IN || | 1397 | session->state == ISCSI_STATE_LOGGED_IN || |
@@ -1348,14 +1403,14 @@ failed: | |||
1348 | spin_lock_bh(&session->lock); | 1403 | spin_lock_bh(&session->lock); |
1349 | if (session->state == ISCSI_STATE_LOGGED_IN) | 1404 | if (session->state == ISCSI_STATE_LOGGED_IN) |
1350 | iscsi_session_printk(KERN_INFO, session, | 1405 | iscsi_session_printk(KERN_INFO, session, |
1351 | "host reset succeeded\n"); | 1406 | "target reset succeeded\n"); |
1352 | else | 1407 | else |
1353 | goto failed; | 1408 | goto failed; |
1354 | spin_unlock_bh(&session->lock); | 1409 | spin_unlock_bh(&session->lock); |
1355 | mutex_unlock(&session->eh_mutex); | 1410 | mutex_unlock(&session->eh_mutex); |
1356 | return SUCCESS; | 1411 | return SUCCESS; |
1357 | } | 1412 | } |
1358 | EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); | 1413 | EXPORT_SYMBOL_GPL(iscsi_eh_target_reset); |
1359 | 1414 | ||
1360 | static void iscsi_tmf_timedout(unsigned long data) | 1415 | static void iscsi_tmf_timedout(unsigned long data) |
1361 | { | 1416 | { |
@@ -1769,10 +1824,10 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) | |||
1769 | 1824 | ||
1770 | iscsi_suspend_tx(conn); | 1825 | iscsi_suspend_tx(conn); |
1771 | 1826 | ||
1772 | spin_lock(&session->lock); | 1827 | spin_lock_bh(&session->lock); |
1773 | fail_all_commands(conn, sc->device->lun, DID_ERROR); | 1828 | fail_all_commands(conn, sc->device->lun, DID_ERROR); |
1774 | conn->tmf_state = TMF_INITIAL; | 1829 | conn->tmf_state = TMF_INITIAL; |
1775 | spin_unlock(&session->lock); | 1830 | spin_unlock_bh(&session->lock); |
1776 | 1831 | ||
1777 | iscsi_start_tx(conn); | 1832 | iscsi_start_tx(conn); |
1778 | goto done; | 1833 | goto done; |
@@ -1878,6 +1933,7 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, | |||
1878 | int dd_data_size, uint16_t qdepth) | 1933 | int dd_data_size, uint16_t qdepth) |
1879 | { | 1934 | { |
1880 | struct Scsi_Host *shost; | 1935 | struct Scsi_Host *shost; |
1936 | struct iscsi_host *ihost; | ||
1881 | 1937 | ||
1882 | shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size); | 1938 | shost = scsi_host_alloc(sht, sizeof(struct iscsi_host) + dd_data_size); |
1883 | if (!shost) | 1939 | if (!shost) |
@@ -1892,22 +1948,43 @@ struct Scsi_Host *iscsi_host_alloc(struct scsi_host_template *sht, | |||
1892 | qdepth = ISCSI_DEF_CMD_PER_LUN; | 1948 | qdepth = ISCSI_DEF_CMD_PER_LUN; |
1893 | } | 1949 | } |
1894 | shost->cmd_per_lun = qdepth; | 1950 | shost->cmd_per_lun = qdepth; |
1951 | |||
1952 | ihost = shost_priv(shost); | ||
1953 | spin_lock_init(&ihost->lock); | ||
1954 | ihost->state = ISCSI_HOST_SETUP; | ||
1955 | ihost->num_sessions = 0; | ||
1956 | init_waitqueue_head(&ihost->session_removal_wq); | ||
1895 | return shost; | 1957 | return shost; |
1896 | } | 1958 | } |
1897 | EXPORT_SYMBOL_GPL(iscsi_host_alloc); | 1959 | EXPORT_SYMBOL_GPL(iscsi_host_alloc); |
1898 | 1960 | ||
1961 | static void iscsi_notify_host_removed(struct iscsi_cls_session *cls_session) | ||
1962 | { | ||
1963 | iscsi_session_failure(cls_session, ISCSI_ERR_INVALID_HOST); | ||
1964 | } | ||
1965 | |||
1899 | /** | 1966 | /** |
1900 | * iscsi_host_remove - remove host and sessions | 1967 | * iscsi_host_remove - remove host and sessions |
1901 | * @shost: scsi host | 1968 | * @shost: scsi host |
1902 | * | 1969 | * |
1903 | * This will also remove any sessions attached to the host, but if userspace | 1970 | * If there are any sessions left, this will initiate the removal and wait |
1904 | * is managing the session at the same time this will break. TODO: add | 1971 | * for the completion. |
1905 | * refcounting to the netlink iscsi interface so a rmmod or host hot unplug | ||
1906 | * does not remove the memory from under us. | ||
1907 | */ | 1972 | */ |
1908 | void iscsi_host_remove(struct Scsi_Host *shost) | 1973 | void iscsi_host_remove(struct Scsi_Host *shost) |
1909 | { | 1974 | { |
1910 | iscsi_host_for_each_session(shost, iscsi_session_teardown); | 1975 | struct iscsi_host *ihost = shost_priv(shost); |
1976 | unsigned long flags; | ||
1977 | |||
1978 | spin_lock_irqsave(&ihost->lock, flags); | ||
1979 | ihost->state = ISCSI_HOST_REMOVED; | ||
1980 | spin_unlock_irqrestore(&ihost->lock, flags); | ||
1981 | |||
1982 | iscsi_host_for_each_session(shost, iscsi_notify_host_removed); | ||
1983 | wait_event_interruptible(ihost->session_removal_wq, | ||
1984 | ihost->num_sessions == 0); | ||
1985 | if (signal_pending(current)) | ||
1986 | flush_signals(current); | ||
1987 | |||
1911 | scsi_remove_host(shost); | 1988 | scsi_remove_host(shost); |
1912 | } | 1989 | } |
1913 | EXPORT_SYMBOL_GPL(iscsi_host_remove); | 1990 | EXPORT_SYMBOL_GPL(iscsi_host_remove); |
@@ -1923,6 +2000,27 @@ void iscsi_host_free(struct Scsi_Host *shost) | |||
1923 | } | 2000 | } |
1924 | EXPORT_SYMBOL_GPL(iscsi_host_free); | 2001 | EXPORT_SYMBOL_GPL(iscsi_host_free); |
1925 | 2002 | ||
2003 | static void iscsi_host_dec_session_cnt(struct Scsi_Host *shost) | ||
2004 | { | ||
2005 | struct iscsi_host *ihost = shost_priv(shost); | ||
2006 | unsigned long flags; | ||
2007 | |||
2008 | shost = scsi_host_get(shost); | ||
2009 | if (!shost) { | ||
2010 | printk(KERN_ERR "Invalid state. Cannot notify host removal " | ||
2011 | "of session teardown event because host already " | ||
2012 | "removed.\n"); | ||
2013 | return; | ||
2014 | } | ||
2015 | |||
2016 | spin_lock_irqsave(&ihost->lock, flags); | ||
2017 | ihost->num_sessions--; | ||
2018 | if (ihost->num_sessions == 0) | ||
2019 | wake_up(&ihost->session_removal_wq); | ||
2020 | spin_unlock_irqrestore(&ihost->lock, flags); | ||
2021 | scsi_host_put(shost); | ||
2022 | } | ||
2023 | |||
1926 | /** | 2024 | /** |
1927 | * iscsi_session_setup - create iscsi cls session and host and session | 2025 | * iscsi_session_setup - create iscsi cls session and host and session |
1928 | * @iscsit: iscsi transport template | 2026 | * @iscsit: iscsi transport template |
@@ -1943,9 +2041,19 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
1943 | uint16_t cmds_max, int cmd_task_size, | 2041 | uint16_t cmds_max, int cmd_task_size, |
1944 | uint32_t initial_cmdsn, unsigned int id) | 2042 | uint32_t initial_cmdsn, unsigned int id) |
1945 | { | 2043 | { |
2044 | struct iscsi_host *ihost = shost_priv(shost); | ||
1946 | struct iscsi_session *session; | 2045 | struct iscsi_session *session; |
1947 | struct iscsi_cls_session *cls_session; | 2046 | struct iscsi_cls_session *cls_session; |
1948 | int cmd_i, scsi_cmds, total_cmds = cmds_max; | 2047 | int cmd_i, scsi_cmds, total_cmds = cmds_max; |
2048 | unsigned long flags; | ||
2049 | |||
2050 | spin_lock_irqsave(&ihost->lock, flags); | ||
2051 | if (ihost->state == ISCSI_HOST_REMOVED) { | ||
2052 | spin_unlock_irqrestore(&ihost->lock, flags); | ||
2053 | return NULL; | ||
2054 | } | ||
2055 | ihost->num_sessions++; | ||
2056 | spin_unlock_irqrestore(&ihost->lock, flags); | ||
1949 | 2057 | ||
1950 | if (!total_cmds) | 2058 | if (!total_cmds) |
1951 | total_cmds = ISCSI_DEF_XMIT_CMDS_MAX; | 2059 | total_cmds = ISCSI_DEF_XMIT_CMDS_MAX; |
@@ -1958,7 +2066,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
1958 | printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue " | 2066 | printk(KERN_ERR "iscsi: invalid can_queue of %d. can_queue " |
1959 | "must be a power of two that is at least %d.\n", | 2067 | "must be a power of two that is at least %d.\n", |
1960 | total_cmds, ISCSI_TOTAL_CMDS_MIN); | 2068 | total_cmds, ISCSI_TOTAL_CMDS_MIN); |
1961 | return NULL; | 2069 | goto dec_session_count; |
1962 | } | 2070 | } |
1963 | 2071 | ||
1964 | if (total_cmds > ISCSI_TOTAL_CMDS_MAX) { | 2072 | if (total_cmds > ISCSI_TOTAL_CMDS_MAX) { |
@@ -1982,7 +2090,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
1982 | cls_session = iscsi_alloc_session(shost, iscsit, | 2090 | cls_session = iscsi_alloc_session(shost, iscsit, |
1983 | sizeof(struct iscsi_session)); | 2091 | sizeof(struct iscsi_session)); |
1984 | if (!cls_session) | 2092 | if (!cls_session) |
1985 | return NULL; | 2093 | goto dec_session_count; |
1986 | session = cls_session->dd_data; | 2094 | session = cls_session->dd_data; |
1987 | session->cls_session = cls_session; | 2095 | session->cls_session = cls_session; |
1988 | session->host = shost; | 2096 | session->host = shost; |
@@ -2021,6 +2129,7 @@ iscsi_session_setup(struct iscsi_transport *iscsit, struct Scsi_Host *shost, | |||
2021 | 2129 | ||
2022 | if (iscsi_add_session(cls_session, id)) | 2130 | if (iscsi_add_session(cls_session, id)) |
2023 | goto cls_session_fail; | 2131 | goto cls_session_fail; |
2132 | |||
2024 | return cls_session; | 2133 | return cls_session; |
2025 | 2134 | ||
2026 | cls_session_fail: | 2135 | cls_session_fail: |
@@ -2029,6 +2138,8 @@ module_get_fail: | |||
2029 | iscsi_pool_free(&session->cmdpool); | 2138 | iscsi_pool_free(&session->cmdpool); |
2030 | cmdpool_alloc_fail: | 2139 | cmdpool_alloc_fail: |
2031 | iscsi_free_session(cls_session); | 2140 | iscsi_free_session(cls_session); |
2141 | dec_session_count: | ||
2142 | iscsi_host_dec_session_cnt(shost); | ||
2032 | return NULL; | 2143 | return NULL; |
2033 | } | 2144 | } |
2034 | EXPORT_SYMBOL_GPL(iscsi_session_setup); | 2145 | EXPORT_SYMBOL_GPL(iscsi_session_setup); |
@@ -2044,6 +2155,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
2044 | { | 2155 | { |
2045 | struct iscsi_session *session = cls_session->dd_data; | 2156 | struct iscsi_session *session = cls_session->dd_data; |
2046 | struct module *owner = cls_session->transport->owner; | 2157 | struct module *owner = cls_session->transport->owner; |
2158 | struct Scsi_Host *shost = session->host; | ||
2047 | 2159 | ||
2048 | iscsi_pool_free(&session->cmdpool); | 2160 | iscsi_pool_free(&session->cmdpool); |
2049 | 2161 | ||
@@ -2056,6 +2168,7 @@ void iscsi_session_teardown(struct iscsi_cls_session *cls_session) | |||
2056 | kfree(session->ifacename); | 2168 | kfree(session->ifacename); |
2057 | 2169 | ||
2058 | iscsi_destroy_session(cls_session); | 2170 | iscsi_destroy_session(cls_session); |
2171 | iscsi_host_dec_session_cnt(shost); | ||
2059 | module_put(owner); | 2172 | module_put(owner); |
2060 | } | 2173 | } |
2061 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); | 2174 | EXPORT_SYMBOL_GPL(iscsi_session_teardown); |
@@ -2335,8 +2448,10 @@ static void iscsi_start_session_recovery(struct iscsi_session *session, | |||
2335 | * flush queues. | 2448 | * flush queues. |
2336 | */ | 2449 | */ |
2337 | spin_lock_bh(&session->lock); | 2450 | spin_lock_bh(&session->lock); |
2338 | fail_all_commands(conn, -1, | 2451 | if (flag == STOP_CONN_RECOVER) |
2339 | STOP_CONN_RECOVER ? DID_BUS_BUSY : DID_ERROR); | 2452 | fail_all_commands(conn, -1, DID_TRANSPORT_DISRUPTED); |
2453 | else | ||
2454 | fail_all_commands(conn, -1, DID_ERROR); | ||
2340 | flush_control_queues(session, conn); | 2455 | flush_control_queues(session, conn); |
2341 | spin_unlock_bh(&session->lock); | 2456 | spin_unlock_bh(&session->lock); |
2342 | mutex_unlock(&session->eh_mutex); | 2457 | mutex_unlock(&session->eh_mutex); |