Commit ac8f73305eea8a12fdcb6090417eb93a74efbcbd
Committed by
Greg Kroah-Hartman
1 parent
9fcbbac5de
Exists in
master
and in
13 other branches
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>
Showing 9 changed files with 37 additions and 31 deletions Side-by-side Diff
Documentation/connector/cn_test.c
drivers/connector/cn_proc.c
... | ... | @@ -95,7 +95,7 @@ |
95 | 95 | msg->len = sizeof(*ev); |
96 | 96 | msg->flags = 0; /* not used */ |
97 | 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 | |
101 | 101 | void proc_exec_connector(struct task_struct *task) |
... | ... | @@ -122,7 +122,7 @@ |
122 | 122 | msg->ack = 0; /* not used */ |
123 | 123 | msg->len = sizeof(*ev); |
124 | 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 | |
128 | 128 | void proc_id_connector(struct task_struct *task, int which_id) |
... | ... | @@ -163,7 +163,7 @@ |
163 | 163 | msg->ack = 0; /* not used */ |
164 | 164 | msg->len = sizeof(*ev); |
165 | 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 | |
169 | 169 | void proc_sid_connector(struct task_struct *task) |
... | ... | @@ -190,7 +190,7 @@ |
190 | 190 | msg->ack = 0; /* not used */ |
191 | 191 | msg->len = sizeof(*ev); |
192 | 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 | |
196 | 196 | void proc_ptrace_connector(struct task_struct *task, int ptrace_id) |
... | ... | @@ -225,7 +225,7 @@ |
225 | 225 | msg->ack = 0; /* not used */ |
226 | 226 | msg->len = sizeof(*ev); |
227 | 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 | |
231 | 231 | void proc_comm_connector(struct task_struct *task) |
... | ... | @@ -253,7 +253,7 @@ |
253 | 253 | msg->ack = 0; /* not used */ |
254 | 254 | msg->len = sizeof(*ev); |
255 | 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 | |
259 | 259 | void proc_coredump_connector(struct task_struct *task) |
... | ... | @@ -280,7 +280,7 @@ |
280 | 280 | msg->ack = 0; /* not used */ |
281 | 281 | msg->len = sizeof(*ev); |
282 | 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 | |
286 | 286 | void proc_exit_connector(struct task_struct *task) |
... | ... | @@ -309,7 +309,7 @@ |
309 | 309 | msg->ack = 0; /* not used */ |
310 | 310 | msg->len = sizeof(*ev); |
311 | 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 @@ |
343 | 343 | msg->ack = rcvd_ack + 1; |
344 | 344 | msg->len = sizeof(*ev); |
345 | 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 | /** |
drivers/connector/connector.c
... | ... | @@ -50,7 +50,7 @@ |
50 | 50 | * |
51 | 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 | 54 | * received message MUST be the same as in original message, and |
55 | 55 | * acknowledge number MUST be the same + 1. |
56 | 56 | * |
57 | 57 | |
... | ... | @@ -62,8 +62,11 @@ |
62 | 62 | * the acknowledgement number in the original message + 1, then it is |
63 | 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 | */ |
66 | -int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask) | |
68 | +int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 __group, | |
69 | + gfp_t gfp_mask) | |
67 | 70 | { |
68 | 71 | struct cn_callback_entry *__cbq; |
69 | 72 | unsigned int size; |
... | ... | @@ -74,7 +77,9 @@ |
74 | 77 | u32 group = 0; |
75 | 78 | int found = 0; |
76 | 79 | |
77 | - if (!__group) { | |
80 | + if (portid || __group) { | |
81 | + group = __group; | |
82 | + } else { | |
78 | 83 | spin_lock_bh(&dev->cbdev->queue_lock); |
79 | 84 | list_for_each_entry(__cbq, &dev->cbdev->queue_list, |
80 | 85 | callback_entry) { |
81 | 86 | |
... | ... | @@ -88,11 +93,9 @@ |
88 | 93 | |
89 | 94 | if (!found) |
90 | 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 | 99 | return -ESRCH; |
97 | 100 | |
98 | 101 | size = sizeof(*msg) + msg->len; |
... | ... | @@ -113,7 +116,10 @@ |
113 | 116 | |
114 | 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 | } |
118 | 124 | EXPORT_SYMBOL_GPL(cn_netlink_send); |
119 | 125 |
drivers/hv/hv_kvp.c
... | ... | @@ -113,7 +113,7 @@ |
113 | 113 | kvp_msg->kvp_hdr.operation = reg_value; |
114 | 114 | strcpy(version, HV_DRV_VERSION); |
115 | 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 | 117 | kfree(msg); |
118 | 118 | } |
119 | 119 | } |
... | ... | @@ -435,7 +435,7 @@ |
435 | 435 | } |
436 | 436 | |
437 | 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 | 439 | kfree(msg); |
440 | 440 | |
441 | 441 | return; |
drivers/hv/hv_snapshot.c
drivers/md/dm-log-userspace-transfer.c
drivers/video/uvesafb.c
... | ... | @@ -190,7 +190,7 @@ |
190 | 190 | uvfb_tasks[seq] = task; |
191 | 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 | 194 | if (err == -ESRCH) { |
195 | 195 | /* |
196 | 196 | * Try to start the userspace helper if sending |
... | ... | @@ -204,7 +204,7 @@ |
204 | 204 | "helper is installed and executable\n"); |
205 | 205 | } else { |
206 | 206 | v86d_started = 1; |
207 | - err = cn_netlink_send(m, 0, gfp_any()); | |
207 | + err = cn_netlink_send(m, 0, 0, gfp_any()); | |
208 | 208 | if (err == -ENOBUFS) |
209 | 209 | err = 0; |
210 | 210 | } |
drivers/w1/w1_netlink.c
... | ... | @@ -45,7 +45,7 @@ |
45 | 45 | |
46 | 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 | |
51 | 51 | static void w1_send_slave(struct w1_master *dev, u64 rn) |
... | ... | @@ -60,7 +60,7 @@ |
60 | 60 | |
61 | 61 | if (avail < 8) { |
62 | 62 | msg->ack++; |
63 | - cn_netlink_send(msg, 0, GFP_KERNEL); | |
63 | + cn_netlink_send(msg, 0, 0, GFP_KERNEL); | |
64 | 64 | |
65 | 65 | msg->len = sizeof(struct w1_netlink_msg) + |
66 | 66 | sizeof(struct w1_netlink_cmd); |
... | ... | @@ -131,7 +131,7 @@ |
131 | 131 | } |
132 | 132 | |
133 | 133 | msg->ack = 0; |
134 | - cn_netlink_send(msg, 0, GFP_KERNEL); | |
134 | + cn_netlink_send(msg, 0, 0, GFP_KERNEL); | |
135 | 135 | |
136 | 136 | dev->priv = NULL; |
137 | 137 | dev->priv_size = 0; |
... | ... | @@ -173,7 +173,7 @@ |
173 | 173 | |
174 | 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 | 178 | kfree(data); |
179 | 179 | |
... | ... | @@ -316,7 +316,7 @@ |
316 | 316 | mutex_lock(&w1_mlock); |
317 | 317 | list_for_each_entry(m, &w1_masters, w1_master_entry) { |
318 | 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 | 320 | cn->ack++; |
321 | 321 | cn->len = sizeof(struct w1_netlink_msg); |
322 | 322 | w->len = 0; |
... | ... | @@ -329,7 +329,7 @@ |
329 | 329 | id++; |
330 | 330 | } |
331 | 331 | cn->ack = 0; |
332 | - cn_netlink_send(cn, 0, GFP_KERNEL); | |
332 | + cn_netlink_send(cn, 0, 0, GFP_KERNEL); | |
333 | 333 | mutex_unlock(&w1_mlock); |
334 | 334 | |
335 | 335 | kfree(cn); |
... | ... | @@ -364,7 +364,7 @@ |
364 | 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 | 368 | kfree(cmsg); |
369 | 369 | |
370 | 370 | return error; |
include/linux/connector.h
... | ... | @@ -71,7 +71,7 @@ |
71 | 71 | int cn_add_callback(struct cb_id *id, const char *name, |
72 | 72 | void (*callback)(struct cn_msg *, struct netlink_skb_parms *)); |
73 | 73 | void cn_del_callback(struct cb_id *); |
74 | -int cn_netlink_send(struct cn_msg *, u32, gfp_t); | |
74 | +int cn_netlink_send(struct cn_msg *msg, u32 portid, u32 group, gfp_t gfp_mask); | |
75 | 75 | |
76 | 76 | int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, |
77 | 77 | struct cb_id *id, |