]> err.no Git - linux-2.6/commitdiff
[SCSI] iscsi: add transport end point callbacks
authorOr Gerlitz <ogerlitz@voltaire.com>
Wed, 3 May 2006 00:46:36 +0000 (19:46 -0500)
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>
Wed, 10 May 2006 15:11:38 +0000 (10:11 -0500)
add transport end point callbacks so iscsi drivers that cannot connect
from userspace, like iscsi tcp, using sockets do not have to
implement their own socket infrastructure.

Signed-off-by: Or Gerlitz <ogerlitz@voltaire.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/iscsi_tcp.c
drivers/scsi/scsi_transport_iscsi.c
include/scsi/iscsi_if.h
include/scsi/scsi_transport_iscsi.h

index fe00a3f6d2040d48517082637ff7f87855dc7e9c..ac507daacfebf5665b4bdc1063c82b14541d8d50 100644 (file)
@@ -1975,7 +1975,7 @@ iscsi_tcp_conn_destroy(struct iscsi_cls_conn *cls_conn)
 
 static int
 iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
-                   struct iscsi_cls_conn *cls_conn, uint32_t transport_fd,
+                   struct iscsi_cls_conn *cls_conn, uint64_t transport_eph,
                    int is_leading)
 {
        struct iscsi_conn *conn = cls_conn->dd_data;
@@ -1985,7 +1985,7 @@ iscsi_tcp_conn_bind(struct iscsi_cls_session *cls_session,
        int err;
 
        /* lookup for existing socket */
-       sock = sockfd_lookup(transport_fd, &err);
+       sock = sockfd_lookup((int)transport_eph, &err);
        if (!sock) {
                printk(KERN_ERR "iscsi_tcp: sockfd_lookup failed %d\n", err);
                return -EEXIST;
index bc9071d2d212b596a51b9d06daf7cef29456d883..7b7a194822da6b18fb156ef1910dd25806d22950 100644 (file)
@@ -928,6 +928,40 @@ iscsi_set_param(struct iscsi_transport *transport, struct iscsi_uevent *ev)
        return err;
 }
 
+static int
+iscsi_if_transport_ep(struct iscsi_transport *transport,
+                     struct iscsi_uevent *ev, int msg_type)
+{
+       struct sockaddr *dst_addr;
+       int rc = 0;
+
+       switch (msg_type) {
+       case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
+               if (!transport->ep_connect)
+                       return -EINVAL;
+
+               dst_addr = (struct sockaddr *)((char*)ev + sizeof(*ev));
+               rc = transport->ep_connect(dst_addr,
+                                          ev->u.ep_connect.non_blocking,
+                                          &ev->r.ep_connect_ret.handle);
+               break;
+       case ISCSI_UEVENT_TRANSPORT_EP_POLL:
+               if (!transport->ep_poll)
+                       return -EINVAL;
+
+               ev->r.retcode = transport->ep_poll(ev->u.ep_poll.ep_handle,
+                                                  ev->u.ep_poll.timeout_ms);
+               break;
+       case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+               if (!transport->ep_disconnect)
+                       return -EINVAL;
+
+               transport->ep_disconnect(ev->u.ep_disconnect.ep_handle);
+               break;
+       }
+       return rc;
+}
+
 static int
 iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 {
@@ -974,7 +1008,7 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
 
                if (session && conn)
                        ev->r.retcode = transport->bind_conn(session, conn,
-                                       ev->u.b_conn.transport_fd,
+                                       ev->u.b_conn.transport_eph,
                                        ev->u.b_conn.is_leading);
                else
                        err = -EINVAL;
@@ -1009,6 +1043,11 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        case ISCSI_UEVENT_GET_STATS:
                err = iscsi_if_get_stats(transport, nlh);
                break;
+       case ISCSI_UEVENT_TRANSPORT_EP_CONNECT:
+       case ISCSI_UEVENT_TRANSPORT_EP_POLL:
+       case ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT:
+               err = iscsi_if_transport_ep(transport, ev, nlh->nlmsg_type);
+               break;
        default:
                err = -EINVAL;
                break;
index 47524c726ee8c96e6c61fc413038eb5acecaf7f5..feff74e544b76c9bcbb53238fb47471495ac1daa 100644 (file)
@@ -43,6 +43,10 @@ enum iscsi_uevent_e {
        ISCSI_UEVENT_GET_STATS          = UEVENT_BASE + 10,
        ISCSI_UEVENT_GET_PARAM          = UEVENT_BASE + 11,
 
+       ISCSI_UEVENT_TRANSPORT_EP_CONNECT       = UEVENT_BASE + 12,
+       ISCSI_UEVENT_TRANSPORT_EP_POLL          = UEVENT_BASE + 13,
+       ISCSI_UEVENT_TRANSPORT_EP_DISCONNECT    = UEVENT_BASE + 14,
+
        /* up events */
        ISCSI_KEVENT_RECV_PDU           = KEVENT_BASE + 1,
        ISCSI_KEVENT_CONN_ERROR         = KEVENT_BASE + 2,
@@ -69,7 +73,7 @@ struct iscsi_uevent {
                struct msg_bind_conn {
                        uint32_t        sid;
                        uint32_t        cid;
-                       uint32_t        transport_fd;
+                       uint64_t        transport_eph;
                        uint32_t        is_leading;
                } b_conn;
                struct msg_destroy_conn {
@@ -102,6 +106,16 @@ struct iscsi_uevent {
                        uint32_t        sid;
                        uint32_t        cid;
                } get_stats;
+               struct msg_transport_connect {
+                       uint32_t        non_blocking;
+               } ep_connect;
+               struct msg_transport_poll {
+                       uint64_t        ep_handle;
+                       uint32_t        timeout_ms;
+               } ep_poll;
+               struct msg_transport_disconnect {
+                       uint64_t        ep_handle;
+               } ep_disconnect;
        } u;
        union {
                /* messages k -> u */
@@ -124,6 +138,9 @@ struct iscsi_uevent {
                        uint32_t        cid;
                        uint32_t        error; /* enum iscsi_err */
                } connerror;
+               struct msg_transport_connect_ret {
+                       uint64_t        handle;
+               } ep_connect_ret;
        } r;
 } __attribute__ ((aligned (sizeof(uint64_t))));
 
index b332d6e839fe9a7cbbc64fc520a85e101bc16a53..c9e9475c6dfff004b3ac811a3ec89915fde4363e 100644 (file)
@@ -88,7 +88,7 @@ struct iscsi_transport {
                                uint32_t cid);
        int (*bind_conn) (struct iscsi_cls_session *session,
                          struct iscsi_cls_conn *cls_conn,
-                         uint32_t transport_fd, int is_leading);
+                         uint64_t transport_eph, int is_leading);
        int (*start_conn) (struct iscsi_cls_conn *conn);
        void (*stop_conn) (struct iscsi_cls_conn *conn, int flag);
        void (*destroy_conn) (struct iscsi_cls_conn *conn);
@@ -119,6 +119,10 @@ struct iscsi_transport {
        int (*xmit_mgmt_task) (struct iscsi_conn *conn,
                               struct iscsi_mgmt_task *mtask);
        void (*session_recovery_timedout) (struct iscsi_cls_session *session);
+       int (*ep_connect) (struct sockaddr *dst_addr, int non_blocking,
+                          uint64_t *ep_handle);
+       int (*ep_poll) (uint64_t ep_handle, int timeout_ms);
+       void (*ep_disconnect) (uint64_t ep_handle);
 };
 
 /*