Commit ac8f73305eea8a12fdcb6090417eb93a74efbcbd

Authored by David Fries
Committed by Greg Kroah-Hartman
1 parent 9fcbbac5de

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
... ... @@ -145,7 +145,7 @@
145 145  
146 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 149 kfree(m);
150 150 }
151 151  
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  
... ... @@ -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
... ... @@ -98,7 +98,7 @@
98 98 vss_msg->vss_hdr.operation = op;
99 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 102 kfree(msg);
103 103  
104 104 return;
drivers/md/dm-log-userspace-transfer.c
... ... @@ -66,7 +66,7 @@
66 66 msg->seq = tfr->seq;
67 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 71 return r;
72 72 }
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,