diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index a318b48247..d1fa0a76a1 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -714,7 +714,8 @@ static void update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, isc_stdtime_t now); static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - isc_rwlocktype_t *tlocktypep, expire_t reason); + isc_rwlocktype_t *nlocktypep, isc_rwlocktype_t *tlocktypep, + expire_t reason); static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, isc_rwlocktype_t *tlocktypep); @@ -7086,7 +7087,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, header->rdh_ttl + STALE_TTL(header, rbtdb) < now - RBTDB_VIRTUAL) { - expire_header(rbtdb, header, &tlocktype, expire_ttl); + expire_header(rbtdb, header, &nlocktype, &tlocktype, + expire_ttl); } /* @@ -8802,11 +8804,13 @@ rdataset_expire(dns_rdataset_t *rdataset) { dns_rbtnode_t *rbtnode = rdataset->private2; rdatasetheader_t *header = rdataset->private3; isc_rwlocktype_t nlocktype = isc_rwlocktype_none; + isc_rwlocktype_t tlocktype = isc_rwlocktype_none; header--; NODE_WRLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype); - expire_header(rbtdb, header, false, expire_flush); + expire_header(rbtdb, header, &nlocktype, &tlocktype, expire_flush); NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, &nlocktype); + INSIST(tlocktype == isc_rwlocktype_none); } static void @@ -10178,7 +10182,8 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, header = isc_heap_element(rbtdb->heaps[locknum], 1); if (header && header->rdh_ttl < now - RBTDB_VIRTUAL) { - expire_header(rbtdb, header, tlocktypep, expire_ttl); + expire_header(rbtdb, header, &nlocktype, tlocktypep, + expire_ttl); purgecount--; } @@ -10195,7 +10200,8 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, */ ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header, link); - expire_header(rbtdb, header, tlocktypep, expire_lru); + expire_header(rbtdb, header, &nlocktype, tlocktypep, + expire_lru); purgecount--; } @@ -10205,13 +10211,15 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, - isc_rwlocktype_t *tlocktypep, expire_t reason) { + isc_rwlocktype_t *nlocktypep, isc_rwlocktype_t *tlocktypep, + expire_t reason) { set_ttl(rbtdb, header, 0); mark_header_ancient(rbtdb, header); /* * Caller must hold the node (write) lock. */ + INSIST(*nlocktypep == isc_rwlocktype_write); if (isc_refcount_current(&header->node->references) == 0) { isc_rwlocktype_t nlocktype = isc_rwlocktype_write;