diff options
| -rw-r--r-- | drivers/scsi/libiscsi.c | 33 | ||||
| -rw-r--r-- | include/scsi/libiscsi.h | 1 |
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 | */ | ||
| 1830 | void 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 | } | ||
| 1836 | EXPORT_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 | */ | ||
| 1813 | void iscsi_suspend_tx(struct iscsi_conn *conn) | 1846 | void 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, | |||
| 390 | extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | 390 | extern 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); |
| 392 | extern void iscsi_suspend_tx(struct iscsi_conn *conn); | 392 | extern void iscsi_suspend_tx(struct iscsi_conn *conn); |
| 393 | extern void iscsi_suspend_queue(struct iscsi_conn *conn); | ||
| 393 | extern void iscsi_conn_queue_work(struct iscsi_conn *conn); | 394 | extern 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...) \ |
