]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Do not re-add a node to the same prunenodes list
authorMichał Kępień <michal@isc.org>
Fri, 1 Mar 2024 17:12:37 +0000 (18:12 +0100)
committerMichał Kępień <michal@isc.org>
Fri, 1 Mar 2024 17:19:39 +0000 (18:19 +0100)
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 4b6fc97af6f936616a12e733b14ffc450af6df87)

lib/dns/rbtdb.c

index f18a3581289b91e40fb77a3b4850e3b412969e79..bb154824ab441d0fda311ded719636c241377124 100644 (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 {