Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

David Fries and committed by
Greg Kroah-Hartman
ac8f7330 9fcbbac5

+37 -31
+1 -1
Documentation/connector/cn_test.c
··· 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
+9 -9
drivers/connector/cn_proc.c
··· 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 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 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 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 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 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 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 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 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 /**
+13 -7
drivers/connector/connector.c
··· 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 * ··· 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; ··· 77 74 u32 group = 0; 78 75 int found = 0; 79 76 80 - if (!__group) { 77 + if (portid || __group) { 78 + group = __group; 79 + } else { 81 80 spin_lock_bh(&dev->cbdev->queue_lock); 82 81 list_for_each_entry(__cbq, &dev->cbdev->queue_list, 83 82 callback_entry) { ··· 93 88 94 89 if (!found) 95 90 return -ENODEV; 96 - } else { 97 - group = __group; 98 91 } 99 92 100 - if (!netlink_has_listeners(dev->nls, group)) 93 + if (!portid && !netlink_has_listeners(dev->nls, group)) 101 94 return -ESRCH; 102 95 103 96 size = sizeof(*msg) + msg->len; ··· 116 113 117 114 NETLINK_CB(skb).dst_group = group; 118 115 119 - return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask); 116 + if (group) 117 + return netlink_broadcast(dev->nls, skb, portid, group, 118 + gfp_mask); 119 + return netlink_unicast(dev->nls, skb, portid, !(gfp_mask&__GFP_WAIT)); 120 120 } 121 121 EXPORT_SYMBOL_GPL(cn_netlink_send); 122 122
+2 -2
drivers/hv/hv_kvp.c
··· 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 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;
+1 -1
drivers/hv/hv_snapshot.c
··· 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;
+1 -1
drivers/md/dm-log-userspace-transfer.c
··· 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 }
+2 -2
drivers/video/uvesafb.c
··· 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 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 }
+7 -7
drivers/w1/w1_netlink.c
··· 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 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 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 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 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 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 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;
+1 -1
include/linux/connector.h
··· 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,