diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index fe00a3f6d2040d48517082637ff7f87855dc7e9c..ac507daacfebf5665b4bdc1063c82b14541d8d50 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -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; diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index bc9071d2d212b596a51b9d06daf7cef29456d883..7b7a194822da6b18fb156ef1910dd25806d22950 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -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; diff --git a/include/scsi/iscsi_if.h b/include/scsi/iscsi_if.h index 47524c726ee8c96e6c61fc413038eb5acecaf7f5..feff74e544b76c9bcbb53238fb47471495ac1daa 100644 --- a/include/scsi/iscsi_if.h +++ b/include/scsi/iscsi_if.h @@ -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)))); diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index b332d6e839fe9a7cbbc64fc520a85e101bc16a53..c9e9475c6dfff004b3ac811a3ec89915fde4363e 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -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); }; /*