| .. | .. |
|---|
| 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, |
|---|