summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2006-10-17 00:09:39 +0200
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-10-26 00:13:53 +0200
commit98644047916c24258fb47c3dab2bed8a44f53b83 (patch)
tree06b94a000abae5d4710786cc57a5ec424e09cc12 /drivers
parent[SCSI] iscsi class: fix slab corruption during restart (diff)
downloadlinux-98644047916c24258fb47c3dab2bed8a44f53b83.tar.xz
linux-98644047916c24258fb47c3dab2bed8a44f53b83.zip
[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')
-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 *))
}
conn = session->leadconn;
+ if (!conn) {
+ reason = FAILURE_SESSION_FREED;
+ goto fault;
+ }
if (!__kfifo_get(session->cmdpool.queue, (void*)&ctask,
sizeof(void*))) {
@@ -1377,7 +1381,6 @@ iscsi_session_setup(struct iscsi_transport *iscsit,
}
spin_lock_init(&session->lock);
- INIT_LIST_HEAD(&session->connections);
/* initialize immediate command pool */
if (iscsi_pool_init(&session->mgmtpool, session->mgmtpool_max,
@@ -1580,16 +1583,11 @@ void iscsi_conn_teardown(struct iscsi_cls_conn *cls_conn)
kfree(conn->persistent_address);
__kfifo_put(session->mgmtpool.queue, (void*)&conn->login_mtask,
sizeof(void*));
- list_del(&conn->item);
- if (list_empty(&session->connections))
+ if (session->leadconn == conn) {
session->leadconn = NULL;
- if (session->leadconn && session->leadconn == conn)
- session->leadconn = container_of(session->connections.next,
- struct iscsi_conn, item);
-
- if (session->leadconn == NULL)
/* no connections exits.. reset sequencing */
session->cmdsn = session->max_cmdsn = session->exp_cmdsn = 1;
+ }
spin_unlock_bh(&session->lock);
kfifo_free(conn->immqueue);
@@ -1777,32 +1775,12 @@ int iscsi_conn_bind(struct iscsi_cls_session *cls_session,
struct iscsi_cls_conn *cls_conn, int is_leading)
{
struct iscsi_session *session = class_to_transport_session(cls_session);
- struct iscsi_conn *tmp = ERR_PTR(-EEXIST), *conn = cls_conn->dd_data;
+ struct iscsi_conn *conn = cls_conn->dd_data;
- /* lookup for existing connection */
spin_lock_bh(&session->lock);
- list_for_each_entry(tmp, &session->connections, item) {
- if (tmp == conn) {
- if (conn->c_stage != ISCSI_CONN_STOPPED ||
- conn->stop_stage == STOP_CONN_TERM) {
- printk(KERN_ERR "iscsi: can't bind "
- "non-stopped connection (%d:%d)\n",
- conn->c_stage, conn->stop_stage);
- spin_unlock_bh(&session->lock);
- return -EIO;
- }
- break;
- }
- }
- if (tmp != conn) {
- /* bind new iSCSI connection to session */
- conn->session = session;
- list_add(&conn->item, &session->connections);
- }
- spin_unlock_bh(&session->lock);
-
if (is_leading)
session->leadconn = conn;
+ spin_unlock_bh(&session->lock);
/*
* Unblock xmitworker(), Login Phase will pass through.