]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove INSIST from from new_reference
authorMark Andrews <marka@isc.org>
Tue, 2 Jun 2020 02:38:40 +0000 (12:38 +1000)
committerMichał Kępień <michal@isc.org>
Tue, 9 Jun 2020 14:24:23 +0000 (16:24 +0200)
RBTDB node can now appear on the deadnodes lists following the changes
to decrement_reference in 4db29f1f7d8544d22d8181d4789d4975eb1dca06 to
defer checking of node->down when the tree write lock is not held.  The
node should be unlinked instead.

(cherry picked from commit 569cc155b8680d8ed12db1fabbe20947db24a0f9)

lib/dns/rbtdb.c

index 8b4e0145bf44c1bc0dc67959a0917eac3a5ac2b2..04d41c9add08eab3ef16d9dad0507bdd762a377b 100644 (file)
@@ -2090,11 +2090,16 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
  * Caller must be holding the node lock.
  */
 static inline void
-new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
+new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
+             isc_rwlocktype_t locktype) {
        unsigned int lockrefs, noderefs;
        isc_refcount_t *lockref;
 
-       INSIST(!ISC_LINK_LINKED(node, deadlink));
+       if (locktype == isc_rwlocktype_write && ISC_LINK_LINKED(node, deadlink))
+       {
+               ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node,
+                               deadlink);
+       }
        dns_rbtnode_refincrement0(node, &noderefs);
        if (noderefs == 1) {    /* this is the first reference to the node */
                lockref = &rbtdb->node_locks[node->locknum].references;
@@ -2114,15 +2119,14 @@ is_leaf(dns_rbtnode_t *node) {
 }
 
 static inline void
-send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
+send_to_prune_tree(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
+                  isc_rwlocktype_t locktype) {
        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);
+       ev = isc_event_allocate(rbtdb->common.mctx, NULL, DNS_EVENT_RBTPRUNE,
+                               prune_tree, node, sizeof(isc_event_t));
+       new_reference(rbtdb, node, locktype);
        db = NULL;
        attach((dns_db_t *)rbtdb, &db);
        ev->ev_sender = db;
@@ -2158,7 +2162,7 @@ cleanup_dead_nodes(dns_rbtdb_t *rbtdb, int bucketnum) {
                       node->data == NULL);
 
                if (is_leaf(node) && rbtdb->task != NULL) {
-                       send_to_prune_tree(rbtdb, node);
+                       send_to_prune_tree(rbtdb, node, isc_rwlocktype_write);
                } else if (node->down == NULL && node->data == NULL) {
                        /*
                         * Not a interior node and not needing to be
@@ -2225,7 +2229,7 @@ reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
                        cleanup_dead_nodes(rbtdb, node->locknum);
        }
 
-       new_reference(rbtdb, node);
+       new_reference(rbtdb, node, locktype);
 
        NODE_WEAKUNLOCK(nodelock, locktype);
        NODE_STRONGUNLOCK(nodelock);
@@ -2365,15 +2369,17 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
                 * periodic walk-through).
                 */
                if (!pruning && is_leaf(node) && rbtdb->task != NULL) {
-                       send_to_prune_tree(rbtdb, node);
+                       send_to_prune_tree(rbtdb, node, isc_rwlocktype_write);
                        no_reference = false;
                } else {
                        delete_node(rbtdb, node);
                }
        } else {
                INSIST(node->data == NULL);
-               INSIST(!ISC_LINK_LINKED(node, deadlink));
-               ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink);
+               if (!ISC_LINK_LINKED(node, deadlink)) {
+                       ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node,
+                                       deadlink);
+               }
        }
 
  restore_locks:
@@ -2438,17 +2444,16 @@ prune_tree(isc_task_t *task, isc_event_t *event) {
 
                        /*
                         * We need to gain a reference to the node before
-                        * decrementing it in the next iteration.  In addition,
-                        * if the node is in the dead-nodes list, extract it
-                        * from the list beforehand as we do in
-                        * reactivate_node().
+                        * decrementing it in the next iteration.
                         */
-                       if (ISC_LINK_LINKED(parent, deadlink))
+                       if (ISC_LINK_LINKED(parent, deadlink)) {
                                ISC_LIST_UNLINK(rbtdb->deadnodes[locknum],
                                                parent, deadlink);
-                       new_reference(rbtdb, parent);
-               } else
+                       }
+                       new_reference(rbtdb, parent, isc_rwlocktype_write);
+               } else {
                        parent = NULL;
+               }
 
                node = parent;
        } while (node != NULL);
@@ -3227,7 +3232,7 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
                 * We increment the reference count on node to ensure that
                 * search->zonecut_rdataset will still be valid later.
                 */
-               new_reference(search->rbtdb, node);
+               new_reference(search->rbtdb, node, isc_rwlocktype_read);
                search->zonecut = node;
                search->zonecut_rdataset = found;
                search->need_cleanup = true;
@@ -3278,11 +3283,10 @@ zone_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
 }
 
 static inline void
-bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
-             rdatasetheader_t *header, isc_stdtime_t now,
-             dns_rdataset_t *rdataset)
-{
-       unsigned char *raw;     /* RDATASLAB */
+bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header,
+             isc_stdtime_t now, isc_rwlocktype_t locktype,
+             dns_rdataset_t *rdataset) {
+       unsigned char *raw; /* RDATASLAB */
 
        /*
         * Caller must be holding the node reader lock.
@@ -3295,7 +3299,7 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
        if (rdataset == NULL)
                return;
 
-       new_reference(rbtdb, node);
+       new_reference(rbtdb, node, locktype);
 
        INSIST(rdataset->methods == NULL);      /* We must be disassociated. */
 
@@ -3390,11 +3394,13 @@ setup_delegation(rbtdb_search_t *search, dns_dbnode_t **nodep,
                NODE_LOCK(&(search->rbtdb->node_locks[node->locknum].lock),
                          isc_rwlocktype_read);
                bind_rdataset(search->rbtdb, node, search->zonecut_rdataset,
-                             search->now, rdataset);
+                             search->now, isc_rwlocktype_read, rdataset);
                if (sigrdataset != NULL && search->zonecut_sigrdataset != NULL)
+               {
                        bind_rdataset(search->rbtdb, node,
-                                     search->zonecut_sigrdataset,
-                                     search->now, sigrdataset);
+                                     search->zonecut_sigrdataset, search->now,
+                                     isc_rwlocktype_read, sigrdataset);
+               }
                NODE_UNLOCK(&(search->rbtdb->node_locks[node->locknum].lock),
                            isc_rwlocktype_read);
        }
@@ -4038,19 +4044,22 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                                                              foundname, NULL);
                                if (result == ISC_R_SUCCESS) {
                                        if (nodep != NULL) {
-                                               new_reference(search->rbtdb,
-                                                             node);
+                                               new_reference(
+                                                       search->rbtdb, node,
+                                                       isc_rwlocktype_read);
                                                *nodep = node;
                                        }
                                        bind_rdataset(search->rbtdb, node,
                                                      found, search->now,
+                                                     isc_rwlocktype_read,
                                                      rdataset);
-                                       if (foundsig != NULL)
-                                               bind_rdataset(search->rbtdb,
-                                                             node,
-                                                             foundsig,
-                                                             search->now,
-                                                             sigrdataset);
+                                       if (foundsig != NULL) {
+                                               bind_rdataset(
+                                                       search->rbtdb, node,
+                                                       foundsig, search->now,
+                                                       isc_rwlocktype_read,
+                                                       sigrdataset);
+                                       }
                                }
                        } else if (found == NULL && foundsig == NULL) {
                                /*
@@ -4330,7 +4339,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
                                 * ensure that search->zonecut_rdataset will
                                 * still be valid later.
                                 */
-                               new_reference(search.rbtdb, node);
+                               new_reference(search.rbtdb, node,
+                                             isc_rwlocktype_read);
                                search.zonecut = node;
                                search.zonecut_rdataset = header;
                                search.zonecut_sigrdataset = NULL;
@@ -4503,18 +4513,19 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
                        goto node_exit;
                }
                if (nodep != NULL) {
-                       new_reference(search.rbtdb, node);
+                       new_reference(search.rbtdb, node, isc_rwlocktype_read);
                        *nodep = node;
                }
                if ((search.rbtversion->secure == dns_db_secure &&
                     !search.rbtversion->havensec3) ||
                    (search.options & DNS_DBFIND_FORCENSEC) != 0)
                {
-                       bind_rdataset(search.rbtdb, node, nsecheader,
-                                     0, rdataset);
-                       if (nsecsig != NULL)
-                               bind_rdataset(search.rbtdb, node,
-                                             nsecsig, 0, sigrdataset);
+                       bind_rdataset(search.rbtdb, node, nsecheader, 0,
+                                     isc_rwlocktype_read, rdataset);
+                       if (nsecsig != NULL) {
+                               bind_rdataset(search.rbtdb, node, nsecsig, 0,
+                                             isc_rwlocktype_read, sigrdataset);
+                       }
                }
                if (wild)
                        foundname->attributes |= DNS_NAMEATTR_WILDCARD;
@@ -4580,18 +4591,21 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
        }
 
        if (nodep != NULL) {
-               if (!at_zonecut)
-                       new_reference(search.rbtdb, node);
-               else
+               if (!at_zonecut) {
+                       new_reference(search.rbtdb, node, isc_rwlocktype_read);
+               } else {
                        search.need_cleanup = false;
+               }
                *nodep = node;
        }
 
        if (type != dns_rdatatype_any) {
-               bind_rdataset(search.rbtdb, node, found, 0, rdataset);
-               if (foundsig != NULL)
+               bind_rdataset(search.rbtdb, node, found, 0, isc_rwlocktype_read,
+                             rdataset);
+               if (foundsig != NULL) {
                        bind_rdataset(search.rbtdb, node, foundsig, 0,
-                                     sigrdataset);
+                                     isc_rwlocktype_read, sigrdataset);
+               }
        }
 
        if (wild)
@@ -4761,8 +4775,7 @@ cache_zonecut_callback(dns_rbtnode_t *node, dns_name_t *name, void *arg) {
                 * We increment the reference count on node to ensure that
                 * search->zonecut_rdataset will still be valid later.
                 */
-               new_reference(search->rbtdb, node);
-               INSIST(!ISC_LINK_LINKED(node, deadlink));
+               new_reference(search->rbtdb, node, locktype);
                search->zonecut = node;
                search->zonecut_rdataset = dname_header;
                search->zonecut_sigrdataset = sigdname_header;
@@ -4868,14 +4881,16 @@ find_deepest_zonecut(rbtdb_search_t *search, dns_rbtnode_t *node,
                        }
                        result = DNS_R_DELEGATION;
                        if (nodep != NULL) {
-                               new_reference(search->rbtdb, node);
+                               new_reference(search->rbtdb, node, locktype);
                                *nodep = node;
                        }
                        bind_rdataset(search->rbtdb, node, found, search->now,
-                                     rdataset);
-                       if (foundsig != NULL)
+                                     locktype, rdataset);
+                       if (foundsig != NULL) {
                                bind_rdataset(search->rbtdb, node, foundsig,
-                                             search->now, sigrdataset);
+                                             search->now, locktype,
+                                             sigrdataset);
+                       }
                        if (need_headerupdate(found, search->now) ||
                            (foundsig != NULL &&
                             need_headerupdate(foundsig, search->now))) {
@@ -4967,14 +4982,16 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
                if (found != NULL) {
                        result = dns_name_concatenate(name, origin,
                                                      foundname, NULL);
-                       if (result != ISC_R_SUCCESS)
+                       if (result != ISC_R_SUCCESS) {
                                goto unlock_node;
-                       bind_rdataset(search->rbtdb, node, found,
-                                     now, rdataset);
-                       if (foundsig != NULL)
+                       }
+                       bind_rdataset(search->rbtdb, node, found, now, locktype,
+                                     rdataset);
+                       if (foundsig != NULL) {
                                bind_rdataset(search->rbtdb, node, foundsig,
-                                             now, sigrdataset);
-                       new_reference(search->rbtdb, node);
+                                             now, locktype, sigrdataset);
+                       }
+                       new_reference(search->rbtdb, node, locktype);
                        *nodep = node;
                        result = DNS_R_COVERINGNSEC;
                } else if (!empty_node) {
@@ -5229,19 +5246,21 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
                 */
                if (nsheader != NULL) {
                        if (nodep != NULL) {
-                               new_reference(search.rbtdb, node);
-                               INSIST(!ISC_LINK_LINKED(node, deadlink));
+                               new_reference(search.rbtdb, node, locktype);
                                *nodep = node;
                        }
                        bind_rdataset(search.rbtdb, node, nsheader, search.now,
-                                     rdataset);
-                       if (need_headerupdate(nsheader, search.now))
+                                     locktype, rdataset);
+                       if (need_headerupdate(nsheader, search.now)) {
                                update = nsheader;
+                       }
                        if (nssig != NULL) {
                                bind_rdataset(search.rbtdb, node, nssig,
-                                             search.now, sigrdataset);
-                               if (need_headerupdate(nssig, search.now))
+                                             search.now, locktype,
+                                             sigrdataset);
+                               if (need_headerupdate(nssig, search.now)) {
                                        updatesig = nssig;
+                               }
                        }
                        result = DNS_R_DELEGATION;
                        goto node_exit;
@@ -5259,8 +5278,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
         */
 
        if (nodep != NULL) {
-               new_reference(search.rbtdb, node);
-               INSIST(!ISC_LINK_LINKED(node, deadlink));
+               new_reference(search.rbtdb, node, locktype);
                *nodep = node;
        }
 
@@ -5289,16 +5307,19 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
        }
 
        if (type != dns_rdatatype_any || result == DNS_R_NCACHENXDOMAIN ||
-           result == DNS_R_NCACHENXRRSET) {
-               bind_rdataset(search.rbtdb, node, found, search.now,
+           result == DNS_R_NCACHENXRRSET)
+       {
+               bind_rdataset(search.rbtdb, node, found, search.now, locktype,
                              rdataset);
-               if (need_headerupdate(found, search.now))
+               if (need_headerupdate(found, search.now)) {
                        update = found;
+               }
                if (!NEGATIVE(found) && foundsig != NULL) {
                        bind_rdataset(search.rbtdb, node, foundsig, search.now,
-                                     sigrdataset);
-                       if (need_headerupdate(foundsig, search.now))
+                                     locktype, sigrdataset);
+                       if (need_headerupdate(foundsig, search.now)) {
                                updatesig = foundsig;
+                       }
                }
        }
 
@@ -5444,15 +5465,16 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
        }
 
        if (nodep != NULL) {
-               new_reference(search.rbtdb, node);
-               INSIST(!ISC_LINK_LINKED(node, deadlink));
+               new_reference(search.rbtdb, node, locktype);
                *nodep = node;
        }
 
-       bind_rdataset(search.rbtdb, node, found, search.now, rdataset);
-       if (foundsig != NULL)
+       bind_rdataset(search.rbtdb, node, found, search.now, locktype,
+                     rdataset);
+       if (foundsig != NULL) {
                bind_rdataset(search.rbtdb, node, foundsig, search.now,
-                             sigrdataset);
+                             locktype, sigrdataset);
+       }
 
        if (need_headerupdate(found, search.now) ||
            (foundsig != NULL &&  need_headerupdate(foundsig, search.now))) {
@@ -5804,10 +5826,12 @@ zone_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                }
        }
        if (found != NULL) {
-               bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
-               if (foundsig != NULL)
+               bind_rdataset(rbtdb, rbtnode, found, now, isc_rwlocktype_read,
+                             rdataset);
+               if (foundsig != NULL) {
                        bind_rdataset(rbtdb, rbtnode, foundsig, now,
-                                     sigrdataset);
+                                     isc_rwlocktype_read, sigrdataset);
+               }
        }
 
        NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
@@ -5892,10 +5916,11 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                }
        }
        if (found != NULL) {
-               bind_rdataset(rbtdb, rbtnode, found, now, rdataset);
-               if (!NEGATIVE(found) && foundsig != NULL)
-                       bind_rdataset(rbtdb, rbtnode, foundsig, now,
+               bind_rdataset(rbtdb, rbtnode, found, now, locktype, rdataset);
+               if (!NEGATIVE(found) && foundsig != NULL) {
+                       bind_rdataset(rbtdb, rbtnode, foundsig, now, locktype,
                                      sigrdataset);
+               }
        }
 
        NODE_UNLOCK(lock, locktype);
@@ -6061,6 +6086,9 @@ resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) {
        return (result);
 }
 
+/*
+ * node write lock must be held.
+ */
 static void
 resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
              rdatasetheader_t *header)
@@ -6073,7 +6101,8 @@ resign_delete(dns_rbtdb_t *rbtdb, rbtdb_version_t *version,
                                header->heap_index);
                header->heap_index = 0;
                if (version != NULL) {
-                       new_reference(rbtdb, header->node);
+                       new_reference(rbtdb, header->node,
+                                     isc_rwlocktype_write);
                        ISC_LIST_APPEND(version->resigned_list, header, link);
                }
        }
@@ -6097,6 +6126,9 @@ update_recordsandbytes(bool add, rbtdb_version_t *rbtversion,
        RWUNLOCK(&rbtversion->rwlock, isc_rwlocktype_write);
 }
 
+/*
+ * write lock on rbtnode must be held.
+ */
 static isc_result_t
 add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
       rdatasetheader_t *newheader, unsigned int options, bool loading,
@@ -6220,10 +6252,13 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                                        free_rdataset(rbtdb,
                                                      rbtdb->common.mctx,
                                                      newheader);
-                                       if (addedrdataset != NULL)
-                                               bind_rdataset(rbtdb, rbtnode,
-                                                             topheader, now,
-                                                             addedrdataset);
+                                       if (addedrdataset != NULL) {
+                                               bind_rdataset(
+                                                       rbtdb, rbtnode,
+                                                       topheader, now,
+                                                       isc_rwlocktype_write,
+                                                       addedrdataset);
+                                       }
                                        return (DNS_R_UNCHANGED);
                                }
                                /*
@@ -6277,6 +6312,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
+                                             isc_rwlocktype_write,
                                              addedrdataset);
                        return (DNS_R_UNCHANGED);
                }
@@ -6376,6 +6412,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
+                                             isc_rwlocktype_write,
                                              addedrdataset);
                        return (ISC_R_SUCCESS);
                }
@@ -6422,6 +6459,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
                        free_rdataset(rbtdb, rbtdb->common.mctx, newheader);
                        if (addedrdataset != NULL)
                                bind_rdataset(rbtdb, rbtnode, header, now,
+                                             isc_rwlocktype_write,
                                              addedrdataset);
                        return (ISC_R_SUCCESS);
                }
@@ -6611,8 +6649,10 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
            cname_and_other_data(rbtnode, rbtversion->serial))
                return (DNS_R_CNAMEANDOTHER);
 
-       if (addedrdataset != NULL)
-               bind_rdataset(rbtdb, rbtnode, newheader, now, addedrdataset);
+       if (addedrdataset != NULL) {
+               bind_rdataset(rbtdb, rbtnode, newheader, now,
+                             isc_rwlocktype_write, addedrdataset);
+       }
 
        return (ISC_R_SUCCESS);
 }
@@ -7145,12 +7185,17 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                        result = DNS_R_UNCHANGED;
        }
 
-       if (result == ISC_R_SUCCESS && newrdataset != NULL)
-               bind_rdataset(rbtdb, rbtnode, newheader, 0, newrdataset);
+       if (result == ISC_R_SUCCESS && newrdataset != NULL) {
+               bind_rdataset(rbtdb, rbtnode, newheader, 0,
+                             isc_rwlocktype_write, newrdataset);
+       }
 
        if (result == DNS_R_NXRRSET && newrdataset != NULL &&
            (options & DNS_DBSUB_WANTOLD) != 0)
-               bind_rdataset(rbtdb, rbtnode, header, 0, newrdataset);
+       {
+               bind_rdataset(rbtdb, rbtnode, header, 0, isc_rwlocktype_write,
+                             newrdataset);
+       }
 
  unlock:
        NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
@@ -8074,7 +8119,7 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
        onode = (dns_rbtnode_t *)rbtdb->origin_node;
        if (onode != NULL) {
                NODE_STRONGLOCK(&rbtdb->node_locks[onode->locknum].lock);
-               new_reference(rbtdb, onode);
+               new_reference(rbtdb, onode, isc_rwlocktype_none);
                NODE_STRONGUNLOCK(&rbtdb->node_locks[onode->locknum].lock);
 
                *nodep = rbtdb->origin_node;
@@ -8269,7 +8314,8 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
                 * Found something; pass back the answer and unlock
                 * the bucket.
                 */
-               bind_rdataset(rbtdb, header->node, header, 0, rdataset);
+               bind_rdataset(rbtdb, header->node, header, 0,
+                             isc_rwlocktype_read, rdataset);
 
                if (foundname != NULL) {
                        dns_rbt_fullnamefromnode(header->node, foundname);
@@ -9256,7 +9302,7 @@ rdatasetiter_current(dns_rdatasetiter_t *iterator, dns_rdataset_t *rdataset) {
                  isc_rwlocktype_read);
 
        bind_rdataset(rbtdb, rbtnode, header, rbtiterator->common.now,
-                     rdataset);
+                     isc_rwlocktype_read, rdataset);
 
        NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
                    isc_rwlocktype_read);
@@ -9692,7 +9738,7 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
                result = ISC_R_SUCCESS;
 
        NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
-       new_reference(rbtdb, node);
+       new_reference(rbtdb, node, isc_rwlocktype_none);
        NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
 
        *nodep = rbtdbiter->node;
@@ -10472,7 +10518,7 @@ expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
                 * We first need to gain a new reference to the node to meet a
                 * requirement of decrement_reference().
                 */
-               new_reference(rbtdb, header->node);
+               new_reference(rbtdb, header->node, isc_rwlocktype_write);
                decrement_reference(rbtdb, header->node, 0,
                                    isc_rwlocktype_write,
                                    tree_locked ? isc_rwlocktype_write :