Skip to content

Commit

Permalink
[SCSI] libiscsi: fix oops in connection create failure path
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mike Christie authored and James Bottomley committed Oct 25, 2006
1 parent 43a145a commit 9864404
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 33 deletions.
38 changes: 8 additions & 30 deletions drivers/scsi/libiscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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*))) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 0 additions & 3 deletions include/scsi/libiscsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ struct iscsi_conn {

/* control data */
int id; /* CID */
struct list_head item; /* maintains list of conns */
int c_stage; /* connection state */
/*
* Preallocated buffer for pdus that have data but do not
Expand Down Expand Up @@ -235,10 +234,8 @@ struct iscsi_session {
* - mgmtpool, *
* - r2tpool */
int state; /* session state */
struct list_head item;
int age; /* counts session re-opens */

struct list_head connections; /* list of connections */
int cmds_max; /* size of cmds array */
struct iscsi_cmd_task **cmds; /* Original Cmds arr */
struct iscsi_queue cmdpool; /* PDU's pool */
Expand Down

0 comments on commit 9864404

Please sign in to comment.