aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libiscsi.c33
-rw-r--r--include/scsi/libiscsi.h1
2 files changed, 34 insertions, 0 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 67b2a2b00286..8dc73c489a17 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1571,6 +1571,12 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
1571 goto fault; 1571 goto fault;
1572 } 1572 }
1573 1573
1574 if (test_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx)) {
1575 reason = FAILURE_SESSION_IN_RECOVERY;
1576 sc->result = DID_REQUEUE;
1577 goto fault;
1578 }
1579
1574 if (iscsi_check_cmdsn_window_closed(conn)) { 1580 if (iscsi_check_cmdsn_window_closed(conn)) {
1575 reason = FAILURE_WINDOW_CLOSED; 1581 reason = FAILURE_WINDOW_CLOSED;
1576 goto reject; 1582 goto reject;
@@ -1810,6 +1816,33 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, unsigned lun,
1810 } 1816 }
1811} 1817}
1812 1818
1819/**
1820 * iscsi_suspend_queue - suspend iscsi_queuecommand
1821 * @conn: iscsi conn to stop queueing IO on
1822 *
1823 * This grabs the session lock to make sure no one is in
1824 * xmit_task/queuecommand, and then sets suspend to prevent
1825 * new commands from being queued. This only needs to be called
1826 * by offload drivers that need to sync a path like ep disconnect
1827 * with the iscsi_queuecommand/xmit_task. To start IO again libiscsi
1828 * will call iscsi_start_tx and iscsi_unblock_session when in FFP.
1829 */
1830void iscsi_suspend_queue(struct iscsi_conn *conn)
1831{
1832 spin_lock_bh(&conn->session->lock);
1833 set_bit(ISCSI_SUSPEND_BIT, &conn->suspend_tx);
1834 spin_unlock_bh(&conn->session->lock);
1835}
1836EXPORT_SYMBOL_GPL(iscsi_suspend_queue);
1837
1838/**
1839 * iscsi_suspend_tx - suspend iscsi_data_xmit
1840 * @conn: iscsi conn tp stop processing IO on.
1841 *
1842 * This function sets the suspend bit to prevent iscsi_data_xmit
1843 * from sending new IO, and if work is queued on the xmit thread
1844 * it will wait for it to be completed.
1845 */
1813void iscsi_suspend_tx(struct iscsi_conn *conn) 1846void iscsi_suspend_tx(struct iscsi_conn *conn)
1814{ 1847{
1815 struct Scsi_Host *shost = conn->session->host; 1848 struct Scsi_Host *shost = conn->session->host;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 439c8b75cb69..887e57e3e223 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -390,6 +390,7 @@ extern void iscsi_session_failure(struct iscsi_session *session,
390extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, 390extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn,
391 enum iscsi_param param, char *buf); 391 enum iscsi_param param, char *buf);
392extern void iscsi_suspend_tx(struct iscsi_conn *conn); 392extern void iscsi_suspend_tx(struct iscsi_conn *conn);
393extern void iscsi_suspend_queue(struct iscsi_conn *conn);
393extern void iscsi_conn_queue_work(struct iscsi_conn *conn); 394extern void iscsi_conn_queue_work(struct iscsi_conn *conn);
394 395
395#define iscsi_conn_printk(prefix, _c, fmt, a...) \ 396#define iscsi_conn_printk(prefix, _c, fmt, a...) \