[SCSI] iscsi class, iscsi_tcp/iser: add host arg to session creation

iscsi offload (bnx2i and qla4xx) allocate a scsi host per hba,
so the session creation path needs a shost/host_no argument.
Software iscsi/iser will follow the same behabior as before
where it allcoates a host per session, but in the future iser
will probably look more like bnx2i where the host's parent is
the hardware (rnic for iser and for bnx2i it is the nic), because
it does not use a socket layer like how iscsi_tcp does.

Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
Mike Christie 2008-05-21 15:53:56 -05:00 committed by James Bottomley
parent d54d48b80f
commit 40753caa36
6 changed files with 51 additions and 13 deletions

View file

@ -368,6 +368,7 @@ static struct iscsi_transport iscsi_iser_transport;
static struct iscsi_cls_session * static struct iscsi_cls_session *
iscsi_iser_session_create(struct iscsi_transport *iscsit, iscsi_iser_session_create(struct iscsi_transport *iscsit,
struct scsi_transport_template *scsit, struct scsi_transport_template *scsit,
struct Scsi_Host *shost,
uint16_t cmds_max, uint16_t qdepth, uint16_t cmds_max, uint16_t qdepth,
uint32_t initial_cmdsn, uint32_t *hostno) uint32_t initial_cmdsn, uint32_t *hostno)
{ {

View file

@ -1871,8 +1871,9 @@ iscsi_conn_get_stats(struct iscsi_cls_conn *cls_conn, struct iscsi_stats *stats)
static struct iscsi_cls_session * static struct iscsi_cls_session *
iscsi_tcp_session_create(struct iscsi_transport *iscsit, iscsi_tcp_session_create(struct iscsi_transport *iscsit,
struct scsi_transport_template *scsit, struct scsi_transport_template *scsit,
uint16_t cmds_max, uint16_t qdepth, struct Scsi_Host *shost, uint16_t cmds_max,
uint32_t initial_cmdsn, uint32_t *hostno) uint16_t qdepth, uint32_t initial_cmdsn,
uint32_t *hostno)
{ {
struct iscsi_cls_session *cls_session; struct iscsi_cls_session *cls_session;
struct iscsi_session *session; struct iscsi_session *session;

View file

@ -1017,21 +1017,38 @@ int iscsi_session_event(struct iscsi_cls_session *session,
EXPORT_SYMBOL_GPL(iscsi_session_event); EXPORT_SYMBOL_GPL(iscsi_session_event);
static int static int
iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev) iscsi_if_create_session(struct iscsi_internal *priv, struct iscsi_uevent *ev,
uint32_t host_no, uint32_t initial_cmdsn,
uint16_t cmds_max, uint16_t queue_depth)
{ {
struct iscsi_transport *transport = priv->iscsi_transport; struct iscsi_transport *transport = priv->iscsi_transport;
struct iscsi_cls_session *session; struct iscsi_cls_session *session;
uint32_t hostno; struct Scsi_Host *shost = NULL;
session = transport->create_session(transport, &priv->t, /*
ev->u.c_session.cmds_max, * Software iscsi allocates a host per session, but
ev->u.c_session.queue_depth, * offload drivers (and possibly iser one day) allocate a host per
ev->u.c_session.initial_cmdsn, * hba/nic/rnic. Offload will match a host here, but software will
&hostno); * return a new hostno after the create_session callback has returned.
*/
if (host_no != UINT_MAX) {
shost = scsi_host_lookup(host_no);
if (IS_ERR(shost)) {
printk(KERN_ERR "Could not find host no %u to "
"create session\n", host_no);
return -ENODEV;
}
}
session = transport->create_session(transport, &priv->t, shost,
cmds_max, queue_depth,
initial_cmdsn, &host_no);
if (shost)
scsi_host_put(shost);
if (!session) if (!session)
return -ENOMEM; return -ENOMEM;
ev->r.c_session_ret.host_no = hostno; ev->r.c_session_ret.host_no = host_no;
ev->r.c_session_ret.sid = session->sid; ev->r.c_session_ret.sid = session->sid;
return 0; return 0;
} }
@ -1190,6 +1207,7 @@ static int
iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{ {
int err = 0; int err = 0;
uint32_t host_no = UINT_MAX;
struct iscsi_uevent *ev = NLMSG_DATA(nlh); struct iscsi_uevent *ev = NLMSG_DATA(nlh);
struct iscsi_transport *transport = NULL; struct iscsi_transport *transport = NULL;
struct iscsi_internal *priv; struct iscsi_internal *priv;
@ -1208,7 +1226,17 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
switch (nlh->nlmsg_type) { switch (nlh->nlmsg_type) {
case ISCSI_UEVENT_CREATE_SESSION: case ISCSI_UEVENT_CREATE_SESSION:
err = iscsi_if_create_session(priv, ev); err = iscsi_if_create_session(priv, ev, host_no,
ev->u.c_session.initial_cmdsn,
ev->u.c_session.cmds_max,
ev->u.c_session.queue_depth);
break;
case ISCSI_UEVENT_CREATE_BOUND_SESSION:
err = iscsi_if_create_session(priv, ev,
ev->u.c_bound_session.host_no,
ev->u.c_bound_session.initial_cmdsn,
ev->u.c_bound_session.cmds_max,
ev->u.c_bound_session.queue_depth);
break; break;
case ISCSI_UEVENT_DESTROY_SESSION: case ISCSI_UEVENT_DESTROY_SESSION:
session = iscsi_session_lookup(ev->u.d_session.sid); session = iscsi_session_lookup(ev->u.d_session.sid);

View file

@ -50,6 +50,7 @@ enum iscsi_uevent_e {
ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15, ISCSI_UEVENT_TGT_DSCVR = UEVENT_BASE + 15,
ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16, ISCSI_UEVENT_SET_HOST_PARAM = UEVENT_BASE + 16,
ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17, ISCSI_UEVENT_UNBIND_SESSION = UEVENT_BASE + 17,
ISCSI_UEVENT_CREATE_BOUND_SESSION = UEVENT_BASE + 18,
/* up events */ /* up events */
ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1, ISCSI_KEVENT_RECV_PDU = KEVENT_BASE + 1,
@ -78,6 +79,12 @@ struct iscsi_uevent {
uint16_t cmds_max; uint16_t cmds_max;
uint16_t queue_depth; uint16_t queue_depth;
} c_session; } c_session;
struct msg_create_bound_session {
uint32_t host_no;
uint32_t initial_cmdsn;
uint16_t cmds_max;
uint16_t queue_depth;
} c_bound_session;
struct msg_destroy_session { struct msg_destroy_session {
uint32_t sid; uint32_t sid;
} d_session; } d_session;

View file

@ -24,6 +24,7 @@
#define LIBISCSI_H #define LIBISCSI_H
#include <linux/types.h> #include <linux/types.h>
#include <linux/wait.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>

View file

@ -92,8 +92,8 @@ struct iscsi_transport {
unsigned int max_conn; unsigned int max_conn;
unsigned int max_cmd_len; unsigned int max_cmd_len;
struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it, struct iscsi_cls_session *(*create_session) (struct iscsi_transport *it,
struct scsi_transport_template *t, uint16_t, uint16_t, struct scsi_transport_template *t, struct Scsi_Host *shost,
uint32_t sn, uint32_t *hn); uint16_t cmds_max, uint16_t qdepth, uint32_t sn, uint32_t *hn);
void (*destroy_session) (struct iscsi_cls_session *session); void (*destroy_session) (struct iscsi_cls_session *session);
struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess, struct iscsi_cls_conn *(*create_conn) (struct iscsi_cls_session *sess,
uint32_t cid); uint32_t cid);