aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c183
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 **/
637static void
638iscsi_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
636static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) 665static 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}
955EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask); 979EXPORT_SYMBOL_GPL(iscsi_itt_to_ctask);
956 980
981void 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}
1011EXPORT_SYMBOL_GPL(iscsi_session_failure);
1012
957void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) 1013void 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}
975EXPORT_SYMBOL_GPL(iscsi_conn_failure); 1032EXPORT_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
1272fault: 1327fault:
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}
1308EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout); 1363EXPORT_SYMBOL_GPL(iscsi_session_recovery_timedout);
1309 1364
1310int iscsi_eh_host_reset(struct scsi_cmnd *sc) 1365int 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) {
1323failed: 1378failed:
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}
1358EXPORT_SYMBOL_GPL(iscsi_eh_host_reset); 1413EXPORT_SYMBOL_GPL(iscsi_eh_target_reset);
1359 1414
1360static void iscsi_tmf_timedout(unsigned long data) 1415static 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}
1897EXPORT_SYMBOL_GPL(iscsi_host_alloc); 1959EXPORT_SYMBOL_GPL(iscsi_host_alloc);
1898 1960
1961static 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 */
1908void iscsi_host_remove(struct Scsi_Host *shost) 1973void 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}
1913EXPORT_SYMBOL_GPL(iscsi_host_remove); 1990EXPORT_SYMBOL_GPL(iscsi_host_remove);
@@ -1923,6 +2000,27 @@ void iscsi_host_free(struct Scsi_Host *shost)
1923} 2000}
1924EXPORT_SYMBOL_GPL(iscsi_host_free); 2001EXPORT_SYMBOL_GPL(iscsi_host_free);
1925 2002
2003static 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
2026cls_session_fail: 2135cls_session_fail:
@@ -2029,6 +2138,8 @@ module_get_fail:
2029 iscsi_pool_free(&session->cmdpool); 2138 iscsi_pool_free(&session->cmdpool);
2030cmdpool_alloc_fail: 2139cmdpool_alloc_fail:
2031 iscsi_free_session(cls_session); 2140 iscsi_free_session(cls_session);
2141dec_session_count:
2142 iscsi_host_dec_session_cnt(shost);
2032 return NULL; 2143 return NULL;
2033} 2144}
2034EXPORT_SYMBOL_GPL(iscsi_session_setup); 2145EXPORT_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}
2061EXPORT_SYMBOL_GPL(iscsi_session_teardown); 2174EXPORT_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);