]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add is_leaf and send_to_prune_tree.
authorMark Andrews <marka@isc.org>
Thu, 5 Dec 2019 23:08:52 +0000 (10:08 +1100)
committerOndřej Surý <ondrej@isc.org>
Tue, 14 Jan 2020 07:36:02 +0000 (08:36 +0100)
Add is_leaf and send_to_prune_tree to make the logic easier
to understand in cleanup_dead_nodes and decrement_reference.

(cherry picked from commit c6efc0e50fd806f48c243baed69b70a7e6473347)

lib/dns/rbtdb.c

index cabd63e9f35c0b9d8c2feb01d8ff7f3251af37ae..c289589fdc2697e7325fbb1fc668cc74594239a7 100644 (file)
@@ -1840,6 +1840,31 @@ new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
        }
 }
 
+/*%
+ * The tree lock must be held for the result to be valid.
+ */
+static inline bool
+is_leaf(dns_rbtnode_t *node) {
+       return (node->parent != NULL && node->parent->down == node &&
+               node->left == NULL && node->right == NULL);
+}
+
+static inline void
+send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
+       isc_event_t *ev;
+       dns_db_t *db;
+
+       ev = isc_event_allocate(rbtdb->common.mctx, NULL,
+                               DNS_EVENT_RBTPRUNE,
+                               prune_tree, node,
+                               sizeof(isc_event_t));
+       new_reference(rbtdb, node);
+       db = NULL;
+       attach((dns_db_t *)rbtdb, &db);
+       ev->ev_sender = db;
+       isc_task_send(rbtdb->task, &ev);
+}
+
 /*%
  * Clean up dead nodes.  These are nodes which have no references, and
  * have no data.  They are dead but we could not or chose not to delete
@@ -1868,22 +1893,8 @@ cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) {
                INSIST(isc_refcount_current(&node->references) == 0 &&
                       node->data == NULL);
 
-               if (node->parent != NULL &&
-                   node->parent->down == node && node->left == NULL &&
-                   node->right == NULL && rbtdb->task != NULL)
-               {
-                       isc_event_t *ev;
-                       dns_db_t *db;
-
-                       ev = isc_event_allocate(rbtdb->common.mctx, NULL,
-                                               DNS_EVENT_RBTPRUNE,
-                                               prune_tree, node,
-                                               sizeof(isc_event_t));
-                       new_reference(rbtdb, node);
-                       db = NULL;
-                       attach((dns_db_t *)rbtdb, &db);
-                       ev->ev_sender = db;
-                       isc_task_send(rbtdb->task, &ev);
+               if (is_leaf(node) && rbtdb->task != NULL) {
+                       send_to_prune_tree(rbtdb, node);
                } else if (node->down == NULL && node->data == NULL) {
                        /*
                         * Not a interior node and not needing to be
@@ -2083,44 +2094,9 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
                 * it's their responsibility to purge stale leaves (e.g. by
                 * periodic walk-through).
                 */
-               if (!pruning && node->parent != NULL &&
-                   node->parent->down == node && node->left == NULL &&
-                   node->right == NULL && rbtdb->task != NULL) {
-                       isc_event_t *ev;
-                       dns_db_t *db;
-
-                       ev = isc_event_allocate(rbtdb->common.mctx, NULL,
-                                               DNS_EVENT_RBTPRUNE,
-                                               prune_tree, node,
-                                               sizeof(isc_event_t));
-                       if (ev != NULL) {
-                               new_reference(rbtdb, node);
-                               db = NULL;
-                               attach((dns_db_t *)rbtdb, &db);
-                               ev->ev_sender = db;
-                               isc_task_send(rbtdb->task, &ev);
-                               no_reference = false;
-                       } else {
-                               /*
-                                * XXX: this is a weird situation.  We could
-                                * ignore this error case, but then the stale
-                                * node will unlikely be purged except via a
-                                * rare condition such as manual cleanup.  So
-                                * we queue it in the deadnodes list, hoping
-                                * the memory shortage is temporary and the node
-                                * will be deleted later.
-                                */
-                               isc_log_write(dns_lctx,
-                                             DNS_LOGCATEGORY_DATABASE,
-                                             DNS_LOGMODULE_CACHE,
-                                             ISC_LOG_INFO,
-                                             "decrement_reference: failed to "
-                                             "allocate pruning event");
-                               INSIST(node->data == NULL);
-                               INSIST(!ISC_LINK_LINKED(node, deadlink));
-                               ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node,
-                                               deadlink);
-                       }
+               if (!pruning && is_leaf(node) && rbtdb->task != NULL) {
+                       send_to_prune_tree(rbtdb, node);
+                       no_reference = false;
                } else {
                        delete_node(rbtdb, node);
                }