diff options
| -rw-r--r-- | drivers/scsi/libiscsi.c | 38 | ||||
| -rw-r--r-- | include/scsi/libiscsi.h | 3 |
2 files changed, 8 insertions, 33 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index c542d0e95e68..1000fe936791 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c | |||
| @@ -778,6 +778,10 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) | |||
| 778 | } | 778 | } |
| 779 | 779 | ||
| 780 | conn = session->leadconn; | 780 | conn = session->leadconn; |
| 781 | if (!conn) { | ||
| 782 | reason = FAILURE_SESSION_FREED; | ||
| 783 | goto fault; | ||
| 784 | } | ||
| 781 | 785 | ||
| 782 | if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, | 786 | if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask, |
| 783 | sizeof(void*))) { | 787 | sizeof(void*))) { |
| @@ -1377,7 +1381,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit, | |||
| 1377 | } | 1381 | } |
| 1378 | 1382 | ||
| 1379 | spin_lock_init(&session->lock); | 1383 | spin_lock_init(&session->lock); |
| 1380 | INIT_LIST_HEAD(&session->connections); | ||
| 1381 | 1384 | ||
| 1382 | /* initialize immediate command pool */ | 1385 | /* initialize immediate command pool */ |
| 1383 | if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, | 1386 | if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max, |
| @@ -1580,16 +1583,11 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn) | |||
| 1580 | kfree(conn->persistent_address); | 1583 | kfree(conn->persistent_address); |
| 1581 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, | 1584 | __kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask, |
| 1582 | sizeof(void*)); | 1585 | sizeof(void*)); |
| 1583 | list_del(&conn->item); | 1586 | if (session->leadconn == conn) { |
| 1584 | if (list_empty(&session->connections)) | ||
| 1585 | session->leadconn = NULL; | 1587 | session->leadconn = NULL; |
| 1586 | if (session->leadconn && session->leadconn == conn) | ||
| 1587 | session->leadconn = container_of(session->connections.next, | ||
| 1588 | struct iscsi_conn, item); | ||
| 1589 | |||
| 1590 | if (session->leadconn == NULL) | ||
| 1591 | /* no connections exits.. reset sequencing */ | 1588 | /* no connections exits.. reset sequencing */ |
| 1592 | session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; | 1589 | session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1; |
| 1590 | } | ||
| 1593 | spin_unlock_bh(&session->lock); | 1591 | spin_unlock_bh(&session->lock); |
| 1594 | 1592 | ||
| 1595 | kfifo_free(conn->immqueue); | 1593 | kfifo_free(conn->immqueue); |
| @@ -1777,32 +1775,12 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session, | |||
| 1777 | struct iscsi_cls_conn *cls_conn, int is_leading) | 1775 | struct iscsi_cls_conn *cls_conn, int is_leading) |
| 1778 | { | 1776 | { |
| 1779 | struct iscsi_session *session = class_to_transport_session(cls_session); | 1777 | struct iscsi_session *session = class_to_transport_session(cls_session); |
| 1780 | struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data; | 1778 | struct iscsi_conn *conn = cls_conn->dd_data; |
| 1781 | 1779 | ||
| 1782 | /* lookup for existing connection */ | ||
| 1783 | spin_lock_bh(&session->lock); | 1780 | spin_lock_bh(&session->lock); |
| 1784 | list_for_each_entry(tmp, &session->connections, item) { | ||
| 1785 | if (tmp == conn) { | ||
| 1786 | if (conn->c_stage != ISCSI_CONN_STOPPED || | ||
| 1787 | conn->stop_stage == STOP_CONN_TERM) { | ||
| 1788 | printk(KERN_ERR "iscsi: can't bind " | ||
| 1789 | "non-stopped connection (%d:%d)\n", | ||
| 1790 | conn->c_stage, conn->stop_stage); | ||
| 1791 | spin_unlock_bh(&session->lock); | ||
| 1792 | return -EIO; | ||
| 1793 | } | ||
| 1794 | break; | ||
| 1795 | } | ||
| 1796 | } | ||
| 1797 | if (tmp != conn) { | ||
| 1798 | /* bind new iSCSI connection to session */ | ||
| 1799 | conn->session = session; | ||
| 1800 | list_add(&conn->item, &session->connections); | ||
| 1801 | } | ||
| 1802 | spin_unlock_bh(&session->lock); | ||
| 1803 | |||
| 1804 | if (is_leading) | 1781 | if (is_leading) |
| 1805 | session->leadconn = conn; | 1782 | session->leadconn = conn; |
| 1783 | spin_unlock_bh(&session->lock); | ||
| 1806 | 1784 | ||
| 1807 | /* | 1785 | /* |
| 1808 | * Unblock xmitworker(), Login Phase will pass through. | 1786 | * Unblock xmitworker(), Login Phase will pass through. |
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 401192e56e50..61eebec00a7b 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h | |||
| @@ -136,7 +136,6 @@ struct iscsi_conn { | |||
| 136 | 136 | ||
| 137 | /* control data */ | 137 | /* control data */ |
| 138 | int id; /* CID */ | 138 | int id; /* CID */ |
| 139 | struct list_head item; /* maintains list of conns */ | ||
| 140 | int c_stage; /* connection state */ | 139 | int c_stage; /* connection state */ |
| 141 | /* | 140 | /* |
| 142 | * Preallocated buffer for pdus that have data but do not | 141 | * Preallocated buffer for pdus that have data but do not |
| @@ -235,10 +234,8 @@ struct iscsi_session { | |||
| 235 | * - mgmtpool, * | 234 | * - mgmtpool, * |
| 236 | * - r2tpool */ | 235 | * - r2tpool */ |
| 237 | int state; /* session state */ | 236 | int state; /* session state */ |
| 238 | struct list_head item; | ||
| 239 | int age; /* counts session re-opens */ | 237 | int age; /* counts session re-opens */ |
| 240 | 238 | ||
| 241 | struct list_head connections; /* list of connections */ | ||
| 242 | int cmds_max; /* size of cmds array */ | 239 | int cmds_max; /* size of cmds array */ |
| 243 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ | 240 | struct iscsi_cmd_task **cmds; /* Original Cmds arr */ |
| 244 | struct iscsi_queue cmdpool; /* PDU's pool */ | 241 | struct iscsi_queue cmdpool; /* PDU's pool */ |
