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 */ |