Do not re-add a node to the same prunenodes list

If a node cleaned up by prune_tree() happens to belong to the same node
bucket as its parent, the latter is directly appended to the prunenodes
list currently processed by prune_tree().  However, the relevant code
branch does not account for the fact that the parent might already be on
the list it is trying to append it to.  Fix by only calling
ISC_LIST_APPEND() for parent nodes not yet added to their relevant
prunenodes list.

(cherry picked from commit 4b6fc97af6)
This commit is contained in:
Michał Kępień 2024-03-01 18:12:37 +01:00
parent a837ba5cd2
commit 37101c7c8a
No known key found for this signature in database

View file

@ -2312,14 +2312,18 @@ prune_tree(isc_task_t *task, isc_event_t *event) {
if (parent->locknum == locknum) {
/*
* Add the parent to the matching prunenodes list
* manually, because send_to_prune_tree() would create
* new event in the case the current node was the last
* node on the prunenodes list.
* The parent belongs to the same node bucket as the
* node we just processed, so there is no need to
* switch node locks. Directly add the parent to the
* prunenodes list we are currently processing (unless
* the parent is already on that list).
*/
new_reference(rbtdb, parent, isc_rwlocktype_write);
ISC_LIST_APPEND(rbtdb->prunenodes[parent->locknum],
parent, prunelink);
if (!ISC_LINK_LINKED(node, prunelink)) {
new_reference(rbtdb, parent,
isc_rwlocktype_write);
ISC_LIST_APPEND(rbtdb->prunenodes[locknum],
parent, prunelink);
}
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
isc_rwlocktype_write);
} else {