diff options
author | David Fries <David@Fries.net> | 2014-01-15 23:29:19 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-07 18:40:17 -0500 |
commit | ac8f73305eea8a12fdcb6090417eb93a74efbcbd (patch) | |
tree | 62e1686b23716165be9ab5de335a0a59bab12908 | |
parent | 9fcbbac5ded489c3a4e121343db999dd51cd6c75 (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.c | 2 | ||||
-rw-r--r-- | drivers/connector/cn_proc.c | 18 | ||||
-rw-r--r-- | drivers/connector/connector.c | 20 | ||||
-rw-r--r-- | drivers/hv/hv_kvp.c | 4 | ||||
-rw-r--r-- | drivers/hv/hv_snapshot.c | 2 | ||||
-rw-r--r-- | drivers/md/dm-log-userspace-transfer.c | 2 | ||||
-rw-r--r-- | drivers/video/uvesafb.c | 4 | ||||
-rw-r--r-- | drivers/w1/w1_netlink.c | 14 | ||||
-rw-r--r-- | include/linux/connector.h | 2 |
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 | ||
101 | void proc_exec_connector(struct task_struct *task) | 101 | void 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 | ||
128 | void proc_id_connector(struct task_struct *task, int which_id) | 128 | 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) | |||
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 | ||
169 | void proc_sid_connector(struct task_struct *task) | 169 | void 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 | ||
196 | void proc_ptrace_connector(struct task_struct *task, int ptrace_id) | 196 | 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) | |||
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 | ||
231 | void proc_comm_connector(struct task_struct *task) | 231 | void 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 | ||
259 | void proc_coredump_connector(struct task_struct *task) | 259 | void 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 | ||
286 | void proc_exit_connector(struct task_struct *task) | 286 | void 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 | */ |
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 | 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 | } |
118 | EXPORT_SYMBOL_GPL(cn_netlink_send); | 124 | EXPORT_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 | ||
51 | static void w1_send_slave(struct w1_master *dev, u64 rn) | 51 | 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) | |||
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 { | |||
71 | int cn_add_callback(struct cb_id *id, const char *name, | 71 | int 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 *)); |
73 | void cn_del_callback(struct cb_id *); | 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 | int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, | 76 | int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name, |
77 | struct cb_id *id, | 77 | struct cb_id *id, |