connector: add portid to unicast in addition to broadcasting
authorDavid Fries <David@Fries.net>
Thu, 16 Jan 2014 04:29:19 +0000 (22:29 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Feb 2014 23:40:17 +0000 (15:40 -0800)
This allows replying only to the requestor portid while still
supporting broadcasting.  Pass 0 to portid for the previous behavior.

Signed-off-by: David Fries <David@Fries.net>
Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/connector/cn_test.c
drivers/connector/cn_proc.c
drivers/connector/connector.c
drivers/hv/hv_kvp.c
drivers/hv/hv_snapshot.c
drivers/md/dm-log-userspace-transfer.c
drivers/video/uvesafb.c
drivers/w1/w1_netlink.c
include/linux/connector.h

index adcca0368d602ff4cb54c10365aa4b3651a4e79b..d12cc944b69621e44b77a7a6f6abc8d3e6b76bb4 100644 (file)
@@ -145,7 +145,7 @@ static void cn_test_timer_func(unsigned long __data)
 
                memcpy(m + 1, data, m->len);
 
-               cn_netlink_send(m, 0, GFP_ATOMIC);
+               cn_netlink_send(m, 0, 0, GFP_ATOMIC);
                kfree(m);
        }
 
index 18c5b9b16645dfa49a218d4b12253240f97310b7..148d707a1d439375ef36bf2ac8e6655fe2a61042 100644 (file)
@@ -95,7 +95,7 @@ void proc_fork_connector(struct task_struct *task)
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
        /*  If cn_netlink_send() failed, the data is not sent */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_exec_connector(struct task_struct *task)
@@ -122,7 +122,7 @@ void proc_exec_connector(struct task_struct *task)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_id_connector(struct task_struct *task, int which_id)
@@ -163,7 +163,7 @@ void proc_id_connector(struct task_struct *task, int which_id)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_sid_connector(struct task_struct *task)
@@ -190,7 +190,7 @@ void proc_sid_connector(struct task_struct *task)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
@@ -225,7 +225,7 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_comm_connector(struct task_struct *task)
@@ -253,7 +253,7 @@ void proc_comm_connector(struct task_struct *task)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_coredump_connector(struct task_struct *task)
@@ -280,7 +280,7 @@ void proc_coredump_connector(struct task_struct *task)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 void proc_exit_connector(struct task_struct *task)
@@ -309,7 +309,7 @@ void proc_exit_connector(struct task_struct *task)
        msg->ack = 0; /* not used */
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 /*
@@ -343,7 +343,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
        msg->ack = rcvd_ack + 1;
        msg->len = sizeof(*ev);
        msg->flags = 0; /* not used */
-       cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+       cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
 }
 
 /**
index a36749f1e44a869418e1bcab6481334948618391..77afe7487d34e4f94b40dd7727571827069b2236 100644 (file)
@@ -50,7 +50,7 @@ static int cn_already_initialized;
  *
  * Sequence number is incremented with each message to be sent.
  *
- * If we expect reply to our message then the sequence number in
+ * If we expect reply to our message then the sequence number in
  * received message MUST be the same as in original message, and
  * acknowledge number MUST be the same + 1.
  *
@@ -62,8 +62,11 @@ static int cn_already_initialized;
  * the acknowledgement number in the original message + 1, then it is
  * a new message.
  *
+ * The message is sent to, the portid if given, the group if given, both if
+ * both, or if both are zero then the group is looked up and sent there.
  */
-int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
+int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group,
+       gfp_t gfp_mask)
 {
        struct cn_callback_entry *__cbq;
        unsigned int size;
@@ -74,7 +77,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
        u32 group = 0;
        int found = 0;
 
-       if (!__group) {
+       if (portid || __group) {
+               group = __group;
+       } else {
                spin_lock_bh(&dev->cbdev->queue_lock);
                list_for_each_entry(__cbq, &dev->cbdev->queue_list,
                                    callback_entry) {
@@ -88,11 +93,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
 
                if (!found)
                        return -ENODEV;
-       } else {
-               group = __group;
        }
 
-       if (!netlink_has_listeners(dev->nls, group))
+       if (!portid && !netlink_has_listeners(dev->nls, group))
                return -ESRCH;
 
        size = sizeof(*msg) + msg->len;
@@ -113,7 +116,10 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
 
        NETLINK_CB(skb).dst_group = group;
 
-       return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask);
+       if (group)
+               return netlink_broadcast(dev->nls, skb, portid, group,
+                                        gfp_mask);
+       return netlink_unicast(dev->nls, skb, portid, !(gfp_mask&__GFP_WAIT));
 }
 EXPORT_SYMBOL_GPL(cn_netlink_send);
 
index 09988b2896226552e4be5cd69d5f09ba3f842d11..ea852537307e8596f5a624ac5f5c44b11286360b 100644 (file)
@@ -113,7 +113,7 @@ kvp_register(int reg_value)
                kvp_msg->kvp_hdr.operation = reg_value;
                strcpy(version, HV_DRV_VERSION);
                msg->len = sizeof(struct hv_kvp_msg);
-               cn_netlink_send(msg, 0, GFP_ATOMIC);
+               cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
                kfree(msg);
        }
 }
@@ -435,7 +435,7 @@ kvp_send_key(struct work_struct *dummy)
        }
 
        msg->len = sizeof(struct hv_kvp_msg);
-       cn_netlink_send(msg, 0, GFP_ATOMIC);
+       cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
        kfree(msg);
 
        return;
index 0c354622437681d1b6dd157f718bb27cf8dbdbed..34f14fddb666bb753c92e3ea955264a862ef8976 100644 (file)
@@ -98,7 +98,7 @@ static void vss_send_op(struct work_struct *dummy)
        vss_msg->vss_hdr.operation = op;
        msg->len = sizeof(struct hv_vss_msg);
 
-       cn_netlink_send(msg, 0, GFP_ATOMIC);
+       cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
        kfree(msg);
 
        return;
index 08d9a207259afdd6fc5ef92afeb403357c1e8a1c..b428c0ae63d5d1e3c173cd0afe9b04072f786415 100644 (file)
@@ -66,7 +66,7 @@ static int dm_ulog_sendto_server(struct dm_ulog_request *tfr)
        msg->seq = tfr->seq;
        msg->len = sizeof(struct dm_ulog_request) + tfr->data_size;
 
-       r = cn_netlink_send(msg, 0, gfp_any());
+       r = cn_netlink_send(msg, 0, 0, gfp_any());
 
        return r;
 }
index 256fba7f46416fb0d5b293e2e0829872d6d344a4..1f38445014c17c85860d88bb0dac0d9086c08102 100644 (file)
@@ -190,7 +190,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
        uvfb_tasks[seq] = task;
        mutex_unlock(&uvfb_lock);
 
-       err = cn_netlink_send(m, 0, GFP_KERNEL);
+       err = cn_netlink_send(m, 0, 0, GFP_KERNEL);
        if (err == -ESRCH) {
                /*
                 * Try to start the userspace helper if sending
@@ -204,7 +204,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
                                        "helper is installed and executable\n");
                } else {
                        v86d_started = 1;
-                       err = cn_netlink_send(m, 0, gfp_any());
+                       err = cn_netlink_send(m, 0, 0, gfp_any());
                        if (err == -ENOBUFS)
                                err = 0;
                }
index 06d614af11669dbe8945776743d746b06fa13460..b63109ada5a7bbaf4898017ed419a7e2eef3c299 100644 (file)
@@ -45,7 +45,7 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
 
        memcpy(w, msg, sizeof(struct w1_netlink_msg));
 
-       cn_netlink_send(m, 0, GFP_KERNEL);
+       cn_netlink_send(m, 0, 0, GFP_KERNEL);
 }
 
 static void w1_send_slave(struct w1_master *dev, u64 rn)
@@ -60,7 +60,7 @@ static void w1_send_slave(struct w1_master *dev, u64 rn)
 
        if (avail < 8) {
                msg->ack++;
-               cn_netlink_send(msg, 0, GFP_KERNEL);
+               cn_netlink_send(msg, 0, 0, GFP_KERNEL);
 
                msg->len = sizeof(struct w1_netlink_msg) +
                        sizeof(struct w1_netlink_cmd);
@@ -131,7 +131,7 @@ static int w1_get_slaves(struct w1_master *dev,
        }
 
        msg->ack = 0;
-       cn_netlink_send(msg, 0, GFP_KERNEL);
+       cn_netlink_send(msg, 0, 0, GFP_KERNEL);
 
        dev->priv = NULL;
        dev->priv_size = 0;
@@ -173,7 +173,7 @@ static int w1_send_read_reply(struct cn_msg *msg, struct w1_netlink_msg *hdr,
 
        memcpy(c->data, cmd->data, c->len);
 
-       err = cn_netlink_send(cm, 0, GFP_KERNEL);
+       err = cn_netlink_send(cm, 0, 0, GFP_KERNEL);
 
        kfree(data);
 
@@ -316,7 +316,7 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
        mutex_lock(&w1_mlock);
        list_for_each_entry(m, &w1_masters, w1_master_entry) {
                if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) {
-                       cn_netlink_send(cn, 0, GFP_KERNEL);
+                       cn_netlink_send(cn, 0, 0, GFP_KERNEL);
                        cn->ack++;
                        cn->len = sizeof(struct w1_netlink_msg);
                        w->len = 0;
@@ -329,7 +329,7 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
                id++;
        }
        cn->ack = 0;
-       cn_netlink_send(cn, 0, GFP_KERNEL);
+       cn_netlink_send(cn, 0, 0, GFP_KERNEL);
        mutex_unlock(&w1_mlock);
 
        kfree(cn);
@@ -364,7 +364,7 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
                cmsg->len += sizeof(*cmd);
        }
 
-       error = cn_netlink_send(cmsg, 0, GFP_KERNEL);
+       error = cn_netlink_send(cmsg, 0, 0, GFP_KERNEL);
        kfree(cmsg);
 
        return error;
index b2b5a41b6a2400342ff5aec1abb4f2834caaf869..be9c4747d51190bcc92a1ae3c6992ae7c6d45018 100644 (file)
@@ -71,7 +71,7 @@ struct cn_dev {
 int cn_add_callback(struct cb_id *id, const char *name,
                    void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
 void cn_del_callback(struct cb_id *);
-int cn_netlink_send(struct cn_msg *, u32, gfp_t);
+int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask);
 
 int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
                          struct cb_id *id,