]> err.no Git - linux-2.6/blobdiff - drivers/scsi/scsi_transport_iscsi.c
[PATCH] W1: cleanups
[linux-2.6] / drivers / scsi / scsi_transport_iscsi.c
index bc9071d2d212b596a51b9d06daf7cef29456d883..5569fdcfd621d3cee2363bc6415a7409dc501380 100644 (file)
 #include <scsi/iscsi_if.h>
 
 #define ISCSI_SESSION_ATTRS 11
-#define ISCSI_CONN_ATTRS 10
+#define ISCSI_CONN_ATTRS 11
 #define ISCSI_HOST_ATTRS 0
 
 struct iscsi_internal {
+       int daemon_pid;
        struct scsi_transport_template t;
        struct iscsi_transport *iscsi_transport;
        struct list_head list;
@@ -145,7 +146,6 @@ static DECLARE_TRANSPORT_CLASS(iscsi_connection_class,
                               NULL);
 
 static struct sock *nls;
-static int daemon_pid;
 static DEFINE_MUTEX(rx_queue_mutex);
 
 struct mempool_zone {
@@ -266,8 +266,8 @@ static void session_recovery_timedout(void *data)
 {
        struct iscsi_cls_session *session = data;
 
-       dev_printk(KERN_INFO, &session->dev, "session recovery timed out "
-                 "after %d secs\n", session->recovery_tmo);
+       dev_printk(KERN_INFO, &session->dev, "iscsi: session recovery timed "
+                 "out after %d secs\n", session->recovery_tmo);
 
        if (session->transport->session_recovery_timedout)
                session->transport->session_recovery_timedout(session);
@@ -572,13 +572,13 @@ mempool_zone_get_skb(struct mempool_zone *zone)
 }
 
 static int
-iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb)
+iscsi_unicast_skb(struct mempool_zone *zone, struct sk_buff *skb, int pid)
 {
        unsigned long flags;
        int rc;
 
        skb_get(skb);
-       rc = netlink_unicast(nls, skb, daemon_pid, MSG_DONTWAIT);
+       rc = netlink_unicast(nls, skb, pid, MSG_DONTWAIT);
        if (rc < 0) {
                mempool_free(skb, zone->pool);
                printk(KERN_ERR "iscsi: can not unicast skb (%d)\n", rc);
@@ -600,9 +600,14 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
        struct sk_buff *skb;
        struct iscsi_uevent *ev;
        char *pdu;
+       struct iscsi_internal *priv;
        int len = NLMSG_SPACE(sizeof(*ev) + sizeof(struct iscsi_hdr) +
                              data_size);
 
+       priv = iscsi_if_transport_lookup(conn->transport);
+       if (!priv)
+               return -EINVAL;
+
        mempool_zone_complete(conn->z_pdu);
 
        skb = mempool_zone_get_skb(conn->z_pdu);
@@ -613,7 +618,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
                return -ENOMEM;
        }
 
-       nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
+       nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
        ev = NLMSG_DATA(nlh);
        memset(ev, 0, sizeof(*ev));
        ev->transport_handle = iscsi_handle(conn->transport);
@@ -626,7 +631,7 @@ int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr,
        memcpy(pdu, hdr, sizeof(struct iscsi_hdr));
        memcpy(pdu + sizeof(struct iscsi_hdr), data, data_size);
 
-       return iscsi_unicast_skb(conn->z_pdu, skb);
+       return iscsi_unicast_skb(conn->z_pdu, skb, priv->daemon_pid);
 }
 EXPORT_SYMBOL_GPL(iscsi_recv_pdu);
 
@@ -635,8 +640,13 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
        struct nlmsghdr *nlh;
        struct sk_buff  *skb;
        struct iscsi_uevent *ev;
+       struct iscsi_internal *priv;
        int len = NLMSG_SPACE(sizeof(*ev));
 
+       priv = iscsi_if_transport_lookup(conn->transport);
+       if (!priv)
+               return;
+
        mempool_zone_complete(conn->z_error);
 
        skb = mempool_zone_get_skb(conn->z_error);
@@ -646,7 +656,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
                return;
        }
 
-       nlh = __nlmsg_put(skb, daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
+       nlh = __nlmsg_put(skb, priv->daemon_pid, 0, 0, (len - sizeof(*nlh)), 0);
        ev = NLMSG_DATA(nlh);
        ev->transport_handle = iscsi_handle(conn->transport);
        ev->type = ISCSI_KEVENT_CONN_ERROR;
@@ -656,7 +666,7 @@ void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error)
        ev->r.connerror.cid = conn->cid;
        ev->r.connerror.sid = iscsi_conn_get_sid(conn);
 
-       iscsi_unicast_skb(conn->z_error, skb);
+       iscsi_unicast_skb(conn->z_error, skb, priv->daemon_pid);
 
        dev_printk(KERN_INFO, &conn->dev, "iscsi: detected conn error (%d)\n",
                   error);
@@ -686,7 +696,7 @@ iscsi_if_send_reply(int pid, int seq, int type, int done, int multi,
        nlh = __nlmsg_put(skb, pid, seq, t, (len - sizeof(*nlh)), 0);
        nlh->nlmsg_flags = flags;
        memcpy(NLMSG_DATA(nlh), payload, size);
-       return iscsi_unicast_skb(z_reply, skb);
+       return iscsi_unicast_skb(z_reply, skb, pid);
 }
 
 static int
@@ -698,12 +708,17 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
        struct iscsi_cls_conn *conn;
        struct nlmsghdr *nlhstat;
        struct iscsi_uevent *evstat;
+       struct iscsi_internal *priv;
        int len = NLMSG_SPACE(sizeof(*ev) +
                              sizeof(struct iscsi_stats) +
                              sizeof(struct iscsi_stats_custom) *
                              ISCSI_STATS_CUSTOM_MAX);
        int err = 0;
 
+       priv = iscsi_if_transport_lookup(transport);
+       if (!priv)
+               return -EINVAL;
+
        conn = iscsi_conn_lookup(ev->u.get_stats.sid, ev->u.get_stats.cid);
        if (!conn)
                return -EEXIST;
@@ -720,7 +735,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
                        return -ENOMEM;
                }
 
-               nlhstat = __nlmsg_put(skbstat, daemon_pid, 0, 0,
+               nlhstat = __nlmsg_put(skbstat, priv->daemon_pid, 0, 0,
                                      (len - sizeof(*nlhstat)), 0);
                evstat = NLMSG_DATA(nlhstat);
                memset(evstat, 0, sizeof(*evstat));
@@ -746,7 +761,7 @@ iscsi_if_get_stats(struct iscsi_transport *transport, struct nlmsghdr *nlh)
                skb_trim(skbstat, NLMSG_ALIGN(actual_size));
                nlhstat->nlmsg_len = actual_size;
 
-               err = iscsi_unicast_skb(conn->z_pdu, skbstat);
+               err = iscsi_unicast_skb(conn->z_pdu, skbstat, priv->daemon_pid);
        } while (err < 0 && err != -ECONNREFUSED);
 
        return err;
@@ -928,6 +943,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)
 {
@@ -947,6 +996,8 @@ iscsi_if_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        if (!try_module_get(transport->owner))
                return -EINVAL;
 
+       priv->daemon_pid = NETLINK_CREDS(skb)->pid;
+
        switch (nlh->nlmsg_type) {
        case ISCSI_UEVENT_CREATE_SESSION:
                err = iscsi_if_create_session(priv, ev);
@@ -974,7 +1025,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 +1060,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;
@@ -1034,7 +1090,6 @@ iscsi_if_rx(struct sock *sk, int len)
                        skb_pull(skb, skb->len);
                        goto free_skb;
                }
-               daemon_pid = NETLINK_CREDS(skb)->pid;
 
                while (skb->len >= NLMSG_SPACE(0)) {
                        int err;
@@ -1117,6 +1172,7 @@ iscsi_conn_int_attr(ifmarker, ISCSI_PARAM_IFMARKER_EN, "%d");
 iscsi_conn_int_attr(ofmarker, ISCSI_PARAM_OFMARKER_EN, "%d");
 iscsi_conn_int_attr(persistent_port, ISCSI_PARAM_PERSISTENT_PORT, "%d");
 iscsi_conn_int_attr(port, ISCSI_PARAM_CONN_PORT, "%d");
+iscsi_conn_int_attr(exp_statsn, ISCSI_PARAM_EXP_STATSN, "%u");
 
 #define iscsi_conn_str_attr_show(param)                                        \
 static ssize_t                                                         \
@@ -1367,6 +1423,7 @@ iscsi_register_transport(struct iscsi_transport *tt)
        SETUP_CONN_RD_ATTR(ofmarker, ISCSI_OFMARKER_EN);
        SETUP_CONN_RD_ATTR(address, ISCSI_CONN_ADDRESS);
        SETUP_CONN_RD_ATTR(port, ISCSI_CONN_PORT);
+       SETUP_CONN_RD_ATTR(exp_statsn, ISCSI_EXP_STATSN);
 
        if (tt->param_mask & ISCSI_PERSISTENT_ADDRESS)
                SETUP_CONN_RD_ATTR(persistent_address, ISCSI_PERSISTENT_ADDRESS);