aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Fries <David@Fries.net>2014-01-15 23:29:19 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-07 18:40:17 -0500
commitac8f73305eea8a12fdcb6090417eb93a74efbcbd (patch)
tree62e1686b23716165be9ab5de335a0a59bab12908
parent9fcbbac5ded489c3a4e121343db999dd51cd6c75 (diff)
connector: add portid to unicast in addition to broadcasting
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>
-rw-r--r--Documentation/connector/cn_test.c2
-rw-r--r--drivers/connector/cn_proc.c18
-rw-r--r--drivers/connector/connector.c20
-rw-r--r--drivers/hv/hv_kvp.c4
-rw-r--r--drivers/hv/hv_snapshot.c2
-rw-r--r--drivers/md/dm-log-userspace-transfer.c2
-rw-r--r--drivers/video/uvesafb.c4
-rw-r--r--drivers/w1/w1_netlink.c14
-rw-r--r--include/linux/connector.h2
9 files changed, 37 insertions, 31 deletions
diff --git a/Documentation/connector/cn_test.c b/Documentation/connector/cn_test.c
index adcca0368d60..d12cc944b696 100644
--- a/Documentation/connector/cn_test.c
+++ b/Documentation/connector/cn_test.c
@@ -145,7 +145,7 @@ static void cn_test_timer_func(unsigned long __data)
145 145
146 memcpy(m + 1, data, m->len); 146 memcpy(m + 1, data, m->len);
147 147
148 cn_netlink_send(m, 0, GFP_ATOMIC); 148 cn_netlink_send(m, 0, 0, GFP_ATOMIC);
149 kfree(m); 149 kfree(m);
150 } 150 }
151 151
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 18c5b9b16645..148d707a1d43 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -95,7 +95,7 @@ void proc_fork_connector(struct task_struct *task)
95 msg->len = sizeof(*ev); 95 msg->len = sizeof(*ev);
96 msg->flags = 0; /* not used */ 96 msg->flags = 0; /* not used */
97 /* If cn_netlink_send() failed, the data is not sent */ 97 /* If cn_netlink_send() failed, the data is not sent */
98 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 98 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
99} 99}
100 100
101void proc_exec_connector(struct task_struct *task) 101void proc_exec_connector(struct task_struct *task)
@@ -122,7 +122,7 @@ void proc_exec_connector(struct task_struct *task)
122 msg->ack = 0; /* not used */ 122 msg->ack = 0; /* not used */
123 msg->len = sizeof(*ev); 123 msg->len = sizeof(*ev);
124 msg->flags = 0; /* not used */ 124 msg->flags = 0; /* not used */
125 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 125 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
126} 126}
127 127
128void proc_id_connector(struct task_struct *task, int which_id) 128void 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)
163 msg->ack = 0; /* not used */ 163 msg->ack = 0; /* not used */
164 msg->len = sizeof(*ev); 164 msg->len = sizeof(*ev);
165 msg->flags = 0; /* not used */ 165 msg->flags = 0; /* not used */
166 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 166 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
167} 167}
168 168
169void proc_sid_connector(struct task_struct *task) 169void proc_sid_connector(struct task_struct *task)
@@ -190,7 +190,7 @@ void proc_sid_connector(struct task_struct *task)
190 msg->ack = 0; /* not used */ 190 msg->ack = 0; /* not used */
191 msg->len = sizeof(*ev); 191 msg->len = sizeof(*ev);
192 msg->flags = 0; /* not used */ 192 msg->flags = 0; /* not used */
193 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 193 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
194} 194}
195 195
196void proc_ptrace_connector(struct task_struct *task, int ptrace_id) 196void 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)
225 msg->ack = 0; /* not used */ 225 msg->ack = 0; /* not used */
226 msg->len = sizeof(*ev); 226 msg->len = sizeof(*ev);
227 msg->flags = 0; /* not used */ 227 msg->flags = 0; /* not used */
228 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 228 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
229} 229}
230 230
231void proc_comm_connector(struct task_struct *task) 231void proc_comm_connector(struct task_struct *task)
@@ -253,7 +253,7 @@ void proc_comm_connector(struct task_struct *task)
253 msg->ack = 0; /* not used */ 253 msg->ack = 0; /* not used */
254 msg->len = sizeof(*ev); 254 msg->len = sizeof(*ev);
255 msg->flags = 0; /* not used */ 255 msg->flags = 0; /* not used */
256 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 256 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
257} 257}
258 258
259void proc_coredump_connector(struct task_struct *task) 259void proc_coredump_connector(struct task_struct *task)
@@ -280,7 +280,7 @@ void proc_coredump_connector(struct task_struct *task)
280 msg->ack = 0; /* not used */ 280 msg->ack = 0; /* not used */
281 msg->len = sizeof(*ev); 281 msg->len = sizeof(*ev);
282 msg->flags = 0; /* not used */ 282 msg->flags = 0; /* not used */
283 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 283 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
284} 284}
285 285
286void proc_exit_connector(struct task_struct *task) 286void proc_exit_connector(struct task_struct *task)
@@ -309,7 +309,7 @@ void proc_exit_connector(struct task_struct *task)
309 msg->ack = 0; /* not used */ 309 msg->ack = 0; /* not used */
310 msg->len = sizeof(*ev); 310 msg->len = sizeof(*ev);
311 msg->flags = 0; /* not used */ 311 msg->flags = 0; /* not used */
312 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 312 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
313} 313}
314 314
315/* 315/*
@@ -343,7 +343,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack)
343 msg->ack = rcvd_ack + 1; 343 msg->ack = rcvd_ack + 1;
344 msg->len = sizeof(*ev); 344 msg->len = sizeof(*ev);
345 msg->flags = 0; /* not used */ 345 msg->flags = 0; /* not used */
346 cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL); 346 cn_netlink_send(msg, 0, CN_IDX_PROC, GFP_KERNEL);
347} 347}
348 348
349/** 349/**
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index a36749f1e44a..77afe7487d34 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -50,7 +50,7 @@ static int cn_already_initialized;
50 * 50 *
51 * Sequence number is incremented with each message to be sent. 51 * Sequence number is incremented with each message to be sent.
52 * 52 *
53 * If we expect reply to our message then the sequence number in 53 * If we expect a reply to our message then the sequence number in
54 * received message MUST be the same as in original message, and 54 * received message MUST be the same as in original message, and
55 * acknowledge number MUST be the same + 1. 55 * acknowledge number MUST be the same + 1.
56 * 56 *
@@ -62,8 +62,11 @@ static int cn_already_initialized;
62 * the acknowledgement number in the original message + 1, then it is 62 * the acknowledgement number in the original message + 1, then it is
63 * a new message. 63 * a new message.
64 * 64 *
65 * The message is sent to, the portid if given, the group if given, both if
66 * both, or if both are zero then the group is looked up and sent there.
65 */ 67 */
66int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask) 68int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group,
69 gfp_t gfp_mask)
67{ 70{
68 struct cn_callback_entry *__cbq; 71 struct cn_callback_entry *__cbq;
69 unsigned int size; 72 unsigned int size;
@@ -74,7 +77,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
74 u32 group = 0; 77 u32 group = 0;
75 int found = 0; 78 int found = 0;
76 79
77 if (!__group) { 80 if (portid || __group) {
81 group = __group;
82 } else {
78 spin_lock_bh(&dev->cbdev->queue_lock); 83 spin_lock_bh(&dev->cbdev->queue_lock);
79 list_for_each_entry(__cbq, &dev->cbdev->queue_list, 84 list_for_each_entry(__cbq, &dev->cbdev->queue_list,
80 callback_entry) { 85 callback_entry) {
@@ -88,11 +93,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
88 93
89 if (!found) 94 if (!found)
90 return -ENODEV; 95 return -ENODEV;
91 } else {
92 group = __group;
93 } 96 }
94 97
95 if (!netlink_has_listeners(dev->nls, group)) 98 if (!portid && !netlink_has_listeners(dev->nls, group))
96 return -ESRCH; 99 return -ESRCH;
97 100
98 size = sizeof(*msg) + msg->len; 101 size = sizeof(*msg) + msg->len;
@@ -113,7 +116,10 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
113 116
114 NETLINK_CB(skb).dst_group = group; 117 NETLINK_CB(skb).dst_group = group;
115 118
116 return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask); 119 if (group)
120 return netlink_broadcast(dev->nls, skb, portid, group,
121 gfp_mask);
122 return netlink_unicast(dev->nls, skb, portid, !(gfp_mask&__GFP_WAIT));
117} 123}
118EXPORT_SYMBOL_GPL(cn_netlink_send); 124EXPORT_SYMBOL_GPL(cn_netlink_send);
119 125
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 09988b289622..ea852537307e 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -113,7 +113,7 @@ kvp_register(int reg_value)
113 kvp_msg->kvp_hdr.operation = reg_value; 113 kvp_msg->kvp_hdr.operation = reg_value;
114 strcpy(version, HV_DRV_VERSION); 114 strcpy(version, HV_DRV_VERSION);
115 msg->len = sizeof(struct hv_kvp_msg); 115 msg->len = sizeof(struct hv_kvp_msg);
116 cn_netlink_send(msg, 0, GFP_ATOMIC); 116 cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
117 kfree(msg); 117 kfree(msg);
118 } 118 }
119} 119}
@@ -435,7 +435,7 @@ kvp_send_key(struct work_struct *dummy)
435 } 435 }
436 436
437 msg->len = sizeof(struct hv_kvp_msg); 437 msg->len = sizeof(struct hv_kvp_msg);
438 cn_netlink_send(msg, 0, GFP_ATOMIC); 438 cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
439 kfree(msg); 439 kfree(msg);
440 440
441 return; 441 return;
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index 0c3546224376..34f14fddb666 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -98,7 +98,7 @@ static void vss_send_op(struct work_struct *dummy)
98 vss_msg->vss_hdr.operation = op; 98 vss_msg->vss_hdr.operation = op;
99 msg->len = sizeof(struct hv_vss_msg); 99 msg->len = sizeof(struct hv_vss_msg);
100 100
101 cn_netlink_send(msg, 0, GFP_ATOMIC); 101 cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
102 kfree(msg); 102 kfree(msg);
103 103
104 return; 104 return;
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index 08d9a207259a..b428c0ae63d5 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -66,7 +66,7 @@ static int dm_ulog_sendto_server(struct dm_ulog_request *tfr)
66 msg->seq = tfr->seq; 66 msg->seq = tfr->seq;
67 msg->len = sizeof(struct dm_ulog_request) + tfr->data_size; 67 msg->len = sizeof(struct dm_ulog_request) + tfr->data_size;
68 68
69 r = cn_netlink_send(msg, 0, gfp_any()); 69 r = cn_netlink_send(msg, 0, 0, gfp_any());
70 70
71 return r; 71 return r;
72} 72}
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 256fba7f4641..1f38445014c1 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -190,7 +190,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
190 uvfb_tasks[seq] = task; 190 uvfb_tasks[seq] = task;
191 mutex_unlock(&uvfb_lock); 191 mutex_unlock(&uvfb_lock);
192 192
193 err = cn_netlink_send(m, 0, GFP_KERNEL); 193 err = cn_netlink_send(m, 0, 0, GFP_KERNEL);
194 if (err == -ESRCH) { 194 if (err == -ESRCH) {
195 /* 195 /*
196 * Try to start the userspace helper if sending 196 * Try to start the userspace helper if sending
@@ -204,7 +204,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
204 "helper is installed and executable\n"); 204 "helper is installed and executable\n");
205 } else { 205 } else {
206 v86d_started = 1; 206 v86d_started = 1;
207 err = cn_netlink_send(m, 0, gfp_any()); 207 err = cn_netlink_send(m, 0, 0, gfp_any());
208 if (err == -ENOBUFS) 208 if (err == -ENOBUFS)
209 err = 0; 209 err = 0;
210 } 210 }
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 06d614af1166..b63109ada5a7 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -45,7 +45,7 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
45 45
46 memcpy(w, msg, sizeof(struct w1_netlink_msg)); 46 memcpy(w, msg, sizeof(struct w1_netlink_msg));
47 47
48 cn_netlink_send(m, 0, GFP_KERNEL); 48 cn_netlink_send(m, 0, 0, GFP_KERNEL);
49} 49}
50 50
51static void w1_send_slave(struct w1_master *dev, u64 rn) 51static 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)
60 60
61 if (avail < 8) { 61 if (avail < 8) {
62 msg->ack++; 62 msg->ack++;
63 cn_netlink_send(msg, 0, GFP_KERNEL); 63 cn_netlink_send(msg, 0, 0, GFP_KERNEL);
64 64
65 msg->len = sizeof(struct w1_netlink_msg) + 65 msg->len = sizeof(struct w1_netlink_msg) +
66 sizeof(struct w1_netlink_cmd); 66 sizeof(struct w1_netlink_cmd);
@@ -131,7 +131,7 @@ static int w1_get_slaves(struct w1_master *dev,
131 } 131 }
132 132
133 msg->ack = 0; 133 msg->ack = 0;
134 cn_netlink_send(msg, 0, GFP_KERNEL); 134 cn_netlink_send(msg, 0, 0, GFP_KERNEL);
135 135
136 dev->priv = NULL; 136 dev->priv = NULL;
137 dev->priv_size = 0; 137 dev->priv_size = 0;
@@ -173,7 +173,7 @@ static int w1_send_read_reply(struct cn_msg *msg, struct w1_netlink_msg *hdr,
173 173
174 memcpy(c->data, cmd->data, c->len); 174 memcpy(c->data, cmd->data, c->len);
175 175
176 err = cn_netlink_send(cm, 0, GFP_KERNEL); 176 err = cn_netlink_send(cm, 0, 0, GFP_KERNEL);
177 177
178 kfree(data); 178 kfree(data);
179 179
@@ -316,7 +316,7 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
316 mutex_lock(&w1_mlock); 316 mutex_lock(&w1_mlock);
317 list_for_each_entry(m, &w1_masters, w1_master_entry) { 317 list_for_each_entry(m, &w1_masters, w1_master_entry) {
318 if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) { 318 if (cn->len + sizeof(*id) > PAGE_SIZE - sizeof(struct cn_msg)) {
319 cn_netlink_send(cn, 0, GFP_KERNEL); 319 cn_netlink_send(cn, 0, 0, GFP_KERNEL);
320 cn->ack++; 320 cn->ack++;
321 cn->len = sizeof(struct w1_netlink_msg); 321 cn->len = sizeof(struct w1_netlink_msg);
322 w->len = 0; 322 w->len = 0;
@@ -329,7 +329,7 @@ static int w1_process_command_root(struct cn_msg *msg, struct w1_netlink_msg *mc
329 id++; 329 id++;
330 } 330 }
331 cn->ack = 0; 331 cn->ack = 0;
332 cn_netlink_send(cn, 0, GFP_KERNEL); 332 cn_netlink_send(cn, 0, 0, GFP_KERNEL);
333 mutex_unlock(&w1_mlock); 333 mutex_unlock(&w1_mlock);
334 334
335 kfree(cn); 335 kfree(cn);
@@ -364,7 +364,7 @@ static int w1_netlink_send_error(struct cn_msg *rcmsg, struct w1_netlink_msg *rm
364 cmsg->len += sizeof(*cmd); 364 cmsg->len += sizeof(*cmd);
365 } 365 }
366 366
367 error = cn_netlink_send(cmsg, 0, GFP_KERNEL); 367 error = cn_netlink_send(cmsg, 0, 0, GFP_KERNEL);
368 kfree(cmsg); 368 kfree(cmsg);
369 369
370 return error; 370 return error;
diff --git a/include/linux/connector.h b/include/linux/connector.h
index b2b5a41b6a24..be9c4747d511 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -71,7 +71,7 @@ struct cn_dev {
71int cn_add_callback(struct cb_id *id, const char *name, 71int cn_add_callback(struct cb_id *id, const char *name,
72 void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); 72 void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
73void cn_del_callback(struct cb_id *); 73void cn_del_callback(struct cb_id *);
74int cn_netlink_send(struct cn_msg *, u32, gfp_t); 74int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask);
75 75
76int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, 76int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
77 struct cb_id *id, 77 struct cb_id *id,