aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-10-16 18:09:39 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-25 18:13:53 -0400
commit98644047916c24258fb47c3dab2bed8a44f53b83 (patch)
tree06b94a000abae5d4710786cc57a5ec424e09cc12 /drivers/scsi
parent43a145a3440c5c5f24ff2888801e40e2242187e6 (diff)
[SCSI] libiscsi: fix oops in connection create failure path
If connection creation fails we end up calling list_del on a invalid struct. This then causes an oops. We are not acutally using the lists (old MCS code we thought might be useful elsewhere) so this patch just removes that code. Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/libiscsi.c38
1 files changed, 8 insertions, 30 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.