aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/scsi/libiscsi.c38
-rw-r--r--include/scsi/libiscsi.h3
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 */