.. | .. |
---|
83 | 83 | |
---|
84 | 84 | node->id = node_id; |
---|
85 | 85 | |
---|
86 | | - radix_tree_insert(&nodes, node_id, node); |
---|
| 86 | + if (radix_tree_insert(&nodes, node_id, node)) { |
---|
| 87 | + kfree(node); |
---|
| 88 | + return NULL; |
---|
| 89 | + } |
---|
87 | 90 | |
---|
88 | 91 | return node; |
---|
89 | 92 | } |
---|
.. | .. |
---|
270 | 273 | return NULL; |
---|
271 | 274 | } |
---|
272 | 275 | |
---|
273 | | -static int server_del(struct qrtr_node *node, unsigned int port) |
---|
| 276 | +static int server_del(struct qrtr_node *node, unsigned int port, bool bcast) |
---|
274 | 277 | { |
---|
275 | 278 | struct qrtr_lookup *lookup; |
---|
276 | 279 | struct qrtr_server *srv; |
---|
.. | .. |
---|
283 | 286 | radix_tree_delete(&node->servers, port); |
---|
284 | 287 | |
---|
285 | 288 | /* Broadcast the removal of local servers */ |
---|
286 | | - if (srv->node == qrtr_ns.local_node) |
---|
| 289 | + if (srv->node == qrtr_ns.local_node && bcast) |
---|
287 | 290 | service_announce_del(&qrtr_ns.bcast_sq, srv); |
---|
288 | 291 | |
---|
289 | 292 | /* Announce the service's disappearance to observers */ |
---|
.. | .. |
---|
369 | 372 | } |
---|
370 | 373 | slot = radix_tree_iter_resume(slot, &iter); |
---|
371 | 374 | rcu_read_unlock(); |
---|
372 | | - server_del(node, srv->port); |
---|
| 375 | + server_del(node, srv->port, true); |
---|
373 | 376 | rcu_read_lock(); |
---|
374 | 377 | } |
---|
375 | 378 | rcu_read_unlock(); |
---|
.. | .. |
---|
455 | 458 | kfree(lookup); |
---|
456 | 459 | } |
---|
457 | 460 | |
---|
458 | | - /* Remove the server belonging to this port */ |
---|
| 461 | + /* Remove the server belonging to this port but don't broadcast |
---|
| 462 | + * DEL_SERVER. Neighbours would've already removed the server belonging |
---|
| 463 | + * to this port due to the DEL_CLIENT broadcast from qrtr_port_remove(). |
---|
| 464 | + */ |
---|
459 | 465 | node = node_get(node_id); |
---|
460 | 466 | if (node) |
---|
461 | | - server_del(node, port); |
---|
| 467 | + server_del(node, port, false); |
---|
462 | 468 | |
---|
463 | 469 | /* Advertise the removal of this client to all local servers */ |
---|
464 | 470 | local_node = node_get(qrtr_ns.local_node); |
---|
.. | .. |
---|
571 | 577 | if (!node) |
---|
572 | 578 | return -ENOENT; |
---|
573 | 579 | |
---|
574 | | - return server_del(node, port); |
---|
| 580 | + return server_del(node, port, true); |
---|
575 | 581 | } |
---|
576 | 582 | |
---|
577 | 583 | static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from, |
---|