2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Add DNS_SLABTOP_FOREACH macros

Add foreach macros to iterate through the dns_slabtop_t
single-linked lists.
This commit is contained in:
Ondřej Surý
2025-08-21 08:56:29 +02:00
parent c60bdbcf5c
commit e3c0a2a0fd
4 changed files with 117 additions and 136 deletions

View File

@@ -79,7 +79,7 @@ PenaltyBreakString: 80
PenaltyExcessCharacter: 100
Standard: Cpp11
ContinuationIndentWidth: 8
ForEachMacros: [ 'cds_lfs_for_each', 'cds_lfs_for_each_safe', 'cds_list_for_each_entry_safe', 'ISC_LIST_FOREACH', 'ISC_LIST_FOREACH_SAFE', 'ISC_LIST_FOREACH_REV', 'ISC_LIST_FOREACH_REV_SAFE', 'MSG_SECTION_FOREACH', 'DNS_DBITERATOR_FOREACH', 'DNS_RDATASET_FOREACH', 'DNS_RDATASETITER_FOREACH', 'CFG_LIST_FOREACH' ]
ForEachMacros: [ 'cds_lfs_for_each', 'cds_lfs_for_each_safe', 'cds_list_for_each_entry_safe', 'ISC_LIST_FOREACH', 'ISC_LIST_FOREACH_SAFE', 'ISC_LIST_FOREACH_REV', 'ISC_LIST_FOREACH_REV_SAFE', 'MSG_SECTION_FOREACH', 'DNS_DBITERATOR_FOREACH', 'DNS_RDATASET_FOREACH', 'DNS_RDATASETITER_FOREACH', 'CFG_LIST_FOREACH', 'DNS_SLABTOP_FOREACH' ]
RemoveParentheses: ReturnStatement
RemoveSemicolon: true
SpaceBeforeParens: ControlStatementsExceptControlMacros

View File

@@ -64,6 +64,12 @@ struct dns_slabheader_proof {
dns_rdatatype_t type;
};
#define DNS_SLABTOP_FOREACH(elt, first) \
for (dns_slabtop_t *elt = first, \
*elt##_next = (elt != NULL) ? elt->next : NULL; \
elt != NULL; \
elt = elt##_next, elt##_next = (elt != NULL) ? elt->next : NULL)
typedef struct dns_slabtop dns_slabtop_t;
struct dns_slabtop {
dns_slabtop_t *next;

View File

@@ -559,14 +559,13 @@ clean_stale_headers(dns_slabheader_t *top) {
static void
clean_cache_node(qpcache_t *qpdb, qpcnode_t *node) {
dns_slabtop_t *top = NULL, *top_prev = NULL, *top_next = NULL;
dns_slabtop_t *top_prev = NULL;
/*
* Caller must be holding the node lock.
*/
for (top = node->data; top != NULL; top = top_next) {
top_next = top->next;
DNS_SLABTOP_FOREACH(top, node->data) {
clean_stale_headers(top->header);
/*
@@ -599,6 +598,7 @@ clean_cache_node(qpcache_t *qpdb, qpcnode_t *node) {
top_prev = top;
}
}
node->dirty = 0;
}
@@ -1275,7 +1275,6 @@ both_headers(dns_slabheader_t *header, dns_rdatatype_t type,
static isc_result_t
check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) {
qpc_search_t *search = arg;
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
isc_result_t result;
isc_rwlock_t *nlock = NULL;
@@ -1289,7 +1288,7 @@ check_zonecut(qpcnode_t *node, void *arg DNS__DB_FLARG) {
/*
* Look for a DNAME or RRSIG DNAME rdataset.
*/
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
if (check_stale_header(top->header, search)) {
continue;
}
@@ -1339,7 +1338,6 @@ find_deepest_zonecut(qpc_search_t *search, qpcnode_t *node,
qpdb = search->qpdb;
for (int i = dns_qpchain_length(&search->chain) - 1; i >= 0; i--) {
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
isc_rwlock_t *nlock = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
@@ -1352,7 +1350,7 @@ find_deepest_zonecut(qpc_search_t *search, qpcnode_t *node,
/*
* Look for NS and RRSIG NS rdatasets.
*/
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
if (check_stale_header(top->header, search)) {
continue;
}
@@ -1415,7 +1413,6 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
dns_slabtop_t *top = NULL;
/*
* Look for the node in the auxilary tree.
@@ -1456,7 +1453,7 @@ find_coveringnsec(qpc_search_t *search, const dns_name_t *name,
nlock = &search->qpdb->buckets[node->locknum].lock;
NODE_RDLOCK(nlock, &nlocktype);
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
if (check_stale_header(top->header, search)) {
continue;
}
@@ -1534,7 +1531,6 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
isc_rwlock_t *nlock = NULL;
isc_rwlocktype_t tlocktype = isc_rwlocktype_none;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *nsheader = NULL;
dns_slabheader_t *foundsig = NULL, *nssig = NULL, *cnamesig = NULL;
dns_slabheader_t *nsecheader = NULL, *nsecsig = NULL;
@@ -1657,7 +1653,7 @@ qpcache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
nsecsig = NULL;
cnamesig = NULL;
empty_node = true;
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
if (check_stale_header(top->header, &search)) {
continue;
}
@@ -1917,14 +1913,13 @@ seek_ns_headers(qpc_search_t *search, qpcnode_t *node, dns_dbnode_t **nodep,
dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
dns_name_t *foundname, dns_name_t *dcname,
isc_rwlocktype_t *tlocktype) {
dns_slabtop_t *top = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = &search->qpdb->buckets[node->locknum].lock;
dns_slabheader_t *found = NULL, *foundsig = NULL;
NODE_RDLOCK(nlock, &nlocktype);
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
bool ns = top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) ||
top->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ns);
if (check_stale_header(top->header, search)) {
@@ -2068,7 +2063,6 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
qpcache_t *qpdb = (qpcache_t *)db;
qpcnode_t *qpnode = (qpcnode_t *)node;
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
dns_typepair_t typepair, sigpair;
isc_result_t result = ISC_R_SUCCESS;
@@ -2095,7 +2089,7 @@ qpcache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
sigpair = (type != dns_rdatatype_rrsig) ? DNS_SIGTYPEPAIR(type)
: dns_typepair_none;
for (top = qpnode->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, qpnode->data) {
if (check_stale_header(top->header, &search)) {
continue;
}
@@ -2543,7 +2537,6 @@ static isc_result_t
add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
unsigned int options, dns_rdataset_t *addedrdataset, isc_stdtime_t now,
isc_rwlocktype_t nlocktype, isc_rwlocktype_t tlocktype DNS__DB_FLARG) {
dns_slabtop_t *top = NULL;
dns_slabtop_t *priotop = NULL, *expiretop = NULL;
dns_slabheader_t *header = NULL, *sigheader = NULL;
dns_trust_t trust;
@@ -2586,9 +2579,7 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
* only rdataset that can be found at this
* node is the negative cache entry.
*/
for (top = qpnode->data; top != NULL;
top = top->next)
{
DNS_SLABTOP_FOREACH(top, qpnode->data) {
mark_ancient(top->header);
}
goto find_header;
@@ -2602,9 +2593,7 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
* above, but just for RRSIGs.
*/
for (top = qpnode->data; top != NULL;
top = top->next)
{
DNS_SLABTOP_FOREACH(top, qpnode->data) {
if (DNS_TYPEPAIR_TYPE(top->typepair) ==
dns_rdatatype_rrsig)
{
@@ -2618,18 +2607,19 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
* Otherwise look for any RRSIGs of the given
* type so they can be marked ancient later.
*/
for (top = qpnode->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, qpnode->data) {
if (top->typepair == sigpair) {
sigheader = top->header;
break;
}
}
} else {
dns_slabtop_t *foundtop = NULL;
/*
* We're adding something that isn't a
* negative cache entry.
*/
for (top = qpnode->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, qpnode->data) {
/*
* Look for any existing negative cache
* entries.
@@ -2643,33 +2633,36 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
* cache anything else.
*/
if (top->typepair == dns_typepair_any) {
foundtop = top;
break;
}
/*
* Don't cache an RRSIG if it cover a type
* Don't cache an RRSIG if it covers a type
* for which we have a cached NODATA record.
*/
if (newheader->typepair == sigpair &&
DNS_TYPEPAIR_TYPE(top->typepair) == covers)
{
foundtop = top;
break;
}
}
if (top != NULL && EXISTS(top->header) &&
ACTIVE(top->header, now))
if (foundtop != NULL && EXISTS(foundtop->header) &&
ACTIVE(foundtop->header, now))
{
/*
* Found one.
*/
if (trust < top->header->trust) {
if (trust < foundtop->header->trust) {
/*
* The NXDOMAIN/NODATA(QTYPE=ANY)
* is more trusted.
*/
bindrdataset(
qpdb, qpnode, top->header, now,
nlocktype, tlocktype,
qpdb, qpnode, foundtop->header,
now, nlocktype, tlocktype,
addedrdataset
DNS__DB_FLARG_PASS);
return DNS_R_UNCHANGED;
@@ -2678,14 +2671,13 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
* The new rdataset is better. Expire the
* ncache entry.
*/
mark_ancient(top->header);
top = NULL;
mark_ancient(foundtop->header);
goto find_header;
}
}
}
for (top = qpnode->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, qpnode->data) {
if (ACTIVE(top->header, now)) {
++ntypes;
expiretop = top;
@@ -2695,16 +2687,17 @@ add(qpcache_t *qpdb, qpcnode_t *qpnode, dns_slabheader_t *newheader,
}
if (top->typepair == newheader->typepair) {
header = top->header;
break;
}
}
find_header:
/*
* If top isn't NULL, we've found the right type.
*/
if (top != NULL) {
header = top->header;
if (header != NULL) {
/*
* We've found the right type.
*/
/*
* Deleting an already non-existent rdataset has no effect.
*/
@@ -2737,13 +2730,13 @@ find_header:
* further down.
*/
if (ACTIVE(header, now) &&
top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
EXISTS(header) && EXISTS(newheader) &&
header->trust >= newheader->trust &&
header->expire < newheader->expire &&
dns_rdataslab_equalx(header, newheader,
qpdb->common.rdclass,
DNS_TYPEPAIR_TYPE(top->typepair)))
DNS_TYPEPAIR_TYPE(header->typepair)))
{
qpcache_hit(qpdb, header);
@@ -2771,7 +2764,7 @@ find_header:
* ensures the delegations that are withdrawn are honoured.
*/
if (ACTIVE(header, now) &&
top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
header->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) &&
EXISTS(header) && EXISTS(newheader) &&
header->trust <= newheader->trust)
{
@@ -2786,10 +2779,10 @@ find_header:
}
if (ACTIVE(header, now) &&
(options & DNS_DBADD_PREFETCH) == 0 &&
(top->typepair == DNS_TYPEPAIR(dns_rdatatype_a) ||
top->typepair == DNS_TYPEPAIR(dns_rdatatype_aaaa) ||
top->typepair == DNS_TYPEPAIR(dns_rdatatype_ds) ||
top->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ds)) &&
(header->typepair == DNS_TYPEPAIR(dns_rdatatype_a) ||
header->typepair == DNS_TYPEPAIR(dns_rdatatype_aaaa) ||
header->typepair == DNS_TYPEPAIR(dns_rdatatype_ds) ||
header->typepair == DNS_SIGTYPEPAIR(dns_rdatatype_ds)) &&
EXISTS(header) && EXISTS(newheader) &&
header->trust >= newheader->trust &&
header->expire < newheader->expire &&
@@ -2815,12 +2808,12 @@ find_header:
return DNS_R_UNCHANGED;
}
top->header = newheader;
newheader->top = top;
header->top->header = newheader;
newheader->top = header->top;
newheader->down = header;
ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve, top,
link);
ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve,
header->top, link);
qpcache_miss(qpdb, newheader, &nlocktype,
&tlocktype DNS__DB_FLARG_PASS);
@@ -3334,26 +3327,26 @@ rdatasetiter_first(dns_rdatasetiter_t *it DNS__DB_FLARG) {
qpc_rditer_t *iterator = (qpc_rditer_t *)it;
qpcache_t *qpdb = (qpcache_t *)(iterator->common.db);
qpcnode_t *qpnode = (qpcnode_t *)iterator->common.node;
dns_slabtop_t *top = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = &qpdb->buckets[qpnode->locknum].lock;
iterator->current = NULL;
NODE_RDLOCK(nlock, &nlocktype);
for (top = qpnode->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, qpnode->data) {
if (EXISTS(top->header) &&
(EXPIREDOK(iterator) ||
iterator_active(qpdb, iterator, top->header)))
{
iterator->current = top;
break;
}
}
NODE_UNLOCK(nlock, &nlocktype);
iterator->current = top;
if (top == NULL) {
if (iterator->current == NULL) {
return ISC_R_NOMORE;
}
@@ -3365,31 +3358,31 @@ rdatasetiter_next(dns_rdatasetiter_t *it DNS__DB_FLARG) {
qpc_rditer_t *iterator = (qpc_rditer_t *)it;
qpcache_t *qpdb = (qpcache_t *)(iterator->common.db);
qpcnode_t *qpnode = (qpcnode_t *)iterator->common.node;
dns_slabtop_t *top = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = &qpdb->buckets[qpnode->locknum].lock;
dns_slabtop_t *next = NULL;
top = iterator->current;
if (top == NULL) {
if (iterator->current == NULL) {
return ISC_R_NOMORE;
}
next = iterator->current->next;
iterator->current = NULL;
NODE_RDLOCK(nlock, &nlocktype);
for (top = top->next; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, next) {
if (EXISTS(top->header) &&
(EXPIREDOK(iterator) ||
iterator_active(qpdb, iterator, top->header)))
{
iterator->current = top;
break;
}
}
NODE_UNLOCK(nlock, &nlocktype);
iterator->current = top;
if (top == NULL) {
if (iterator->current == NULL) {
return ISC_R_NOMORE;
}
@@ -3851,12 +3844,9 @@ static dns_dbmethods_t qpdb_cachemethods = {
static void
qpcnode_destroy(qpcnode_t *qpnode) {
dns_slabtop_t *top = NULL, *top_next = NULL;
qpcache_t *qpdb = qpnode->qpdb;
for (top = qpnode->data; top != NULL; top = top_next) {
top_next = top->next;
DNS_SLABTOP_FOREACH(top, qpnode->data) {
dns_slabheader_t *down = NULL, *down_next = NULL;
for (down = top->header; down != NULL; down = down_next) {
down_next = down->down;

View File

@@ -814,7 +814,7 @@ qpznode_acquire(qpznode_t *node DNS__DB_FLARG) {
static void
clean_zone_node(qpznode_t *node, uint32_t least_serial) {
dns_slabtop_t *top = NULL, *top_prev = NULL, *top_next = NULL;
dns_slabtop_t *top_prev = NULL;
bool still_dirty = false;
/*
@@ -822,9 +822,7 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
*/
REQUIRE(least_serial != 0);
for (top = node->data; top != NULL; top = top_next) {
top_next = top->next;
DNS_SLABTOP_FOREACH(top, node->data) {
INSIST(top->header != NULL);
/*
@@ -1285,7 +1283,6 @@ make_least_version(qpzonedb_t *qpdb, qpz_version_t *version,
static void
rollback_node(qpznode_t *node, uint32_t serial) {
dns_slabtop_t *top = NULL;
bool make_dirty = false;
/*
@@ -1293,7 +1290,7 @@ rollback_node(qpznode_t *node, uint32_t serial) {
* 'serial'. When the reference count goes to zero, these rdatasets
* will be cleaned up; until that time, they will be ignored.
*/
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
if (header->serial == serial) {
@@ -1554,7 +1551,6 @@ qpzone_findrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
qpzonedb_t *qpdb = (qpzonedb_t *)db;
qpznode_t *node = (qpznode_t *)dbnode;
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
uint32_t serial;
qpz_version_t *version = (qpz_version_t *)dbversion;
@@ -1587,7 +1583,7 @@ qpzone_findrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
sigpair = dns_typepair_none;
}
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
do {
if (header->serial <= serial && !IGNORE(header)) {
@@ -1708,14 +1704,13 @@ static bool
cname_and_other(qpznode_t *node, uint32_t serial) {
bool cname = false, other = false;
dns_rdatatype_t rdtype;
dns_slabtop_t *top = NULL;
/*
* Look for CNAME and "other data" rdatasets active in our version.
* ("Other data" is any rdataset whose type is not KEY, NSEC, SIG
* or RRSIG.
*/
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
rdtype = DNS_TYPEPAIR_TYPE(top->typepair);
@@ -1819,7 +1814,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
bool loading, dns_rdataset_t *addedrdataset,
isc_stdtime_t now ISC_ATTR_UNUSED DNS__DB_FLARG) {
qpz_changed_t *changed = NULL;
dns_slabtop_t *top = NULL;
dns_slabtop_t *foundtop = NULL;
dns_slabtop_t *priotop = NULL;
dns_slabheader_t *merged = NULL;
isc_result_t result;
@@ -1842,12 +1837,13 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
}
ntypes = 0;
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
++ntypes;
if (prio_type(top->typepair)) {
priotop = top;
}
if (top->typepair == newheader->typepair) {
foundtop = top;
break;
}
}
@@ -1858,8 +1854,8 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
* data. We skip over them.
*/
dns_slabheader_t *header = NULL, *header_prev = NULL;
if (top != NULL) {
header = top->header;
if (foundtop != NULL) {
header = foundtop->header;
while (header != NULL && IGNORE(header)) {
header_prev = header;
header = header->down;
@@ -1930,8 +1926,8 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
}
}
INSIST(version->serial >= top->header->serial);
INSIST(top->typepair == newheader->typepair);
INSIST(version->serial >= foundtop->header->serial);
INSIST(foundtop->typepair == newheader->typepair);
if (loading) {
newheader->down = NULL;
@@ -1946,8 +1942,8 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
* Since we don't generate changed records when
* loading, we MUST clean up 'header' now.
*/
newheader->top = top;
top->header = newheader;
newheader->top = foundtop;
foundtop->header = newheader;
maybe_update_recordsandsize(false, version, header,
nodename->length);
@@ -1962,10 +1958,10 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
if (header_prev != NULL) {
header_prev->down = newheader;
} else {
top->header = newheader;
foundtop->header = newheader;
}
newheader->top = top;
newheader->top = foundtop;
newheader->down = header;
node->dirty = true;
@@ -1992,7 +1988,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
resigndelete(qpdb, version, header DNS__DB_FLARG_PASS);
}
if (top != NULL) {
if (foundtop != NULL) {
/*
* We have a list of rdatasets of the given type,
* but they're all marked IGNORE. We simply insert
@@ -2002,10 +1998,10 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
* we INSIST on it.
*/
INSIST(!loading);
INSIST(version->serial >= top->header->serial);
newheader->top = top;
newheader->down = top->header;
top->header = newheader;
INSIST(version->serial >= foundtop->header->serial);
newheader->top = foundtop;
newheader->down = foundtop->header;
foundtop->header = newheader;
if (changed != NULL) {
changed->dirty = true;
}
@@ -2673,11 +2669,10 @@ step(qpz_search_t *search, dns_qpiter_t *it, direction_t direction,
while (result == ISC_R_SUCCESS) {
isc_rwlock_t *nlock = qpzone_get_lock(node);
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL;
NODE_RDLOCK(nlock, &nlocktype);
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
while (header != NULL &&
(IGNORE(header) ||
@@ -2810,7 +2805,6 @@ wildcard_blocked(qpz_search_t *search, const dns_name_t *qname,
static isc_result_t
find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname,
dns_namespace_t nspace) {
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL;
isc_result_t result = ISC_R_NOTFOUND;
@@ -2839,7 +2833,7 @@ find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname,
* may not need the information, because it simplifies the
* locking and code flow.
*/
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
if (header->serial <= search->serial &&
!IGNORE(header) && EXISTS(header))
@@ -2879,9 +2873,7 @@ find_wildcard(qpz_search_t *search, qpznode_t **nodep, const dns_name_t *qname,
*/
nlock = qpzone_get_lock(wnode);
NODE_RDLOCK(nlock, &nlocktype);
for (top = wnode->data; top != NULL;
top = top->next)
{
DNS_SLABTOP_FOREACH(top, wnode->data) {
dns_slabheader_t *header = top->header;
if (header->serial <= search->serial &&
!IGNORE(header) && EXISTS(header))
@@ -3055,13 +3047,12 @@ find_closest_nsec(qpz_search_t *search, dns_dbnode_t **nodep,
}
again:
do {
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *foundsig = NULL;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = qpzone_get_lock(node);
NODE_RDLOCK(nlock, &nlocktype);
empty_node = true;
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
/*
* Look for an active, extant NSEC or RRSIG NSEC.
@@ -3192,7 +3183,6 @@ again:
static isc_result_t
qpzone_check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
qpz_search_t *search = arg;
dns_slabtop_t *top = NULL;
dns_slabheader_t *dname_header = NULL, *sigdname_header = NULL;
dns_slabheader_t *ns_header = NULL;
dns_slabheader_t *found = NULL;
@@ -3205,7 +3195,7 @@ qpzone_check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
/*
* Look for an NS or DNAME rdataset active in our version.
*/
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
if (top->typepair == DNS_TYPEPAIR(dns_rdatatype_ns) ||
top->typepair == DNS_TYPEPAIR(dns_rdatatype_dname) ||
@@ -3358,7 +3348,6 @@ qpzone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
bool maybe_zonecut = false, at_zonecut = false;
bool wild = false, empty_node = false;
bool nsec3 = false;
dns_slabtop_t *top = NULL;
dns_slabheader_t *found = NULL, *nsecheader = NULL;
dns_slabheader_t *foundsig = NULL, *cnamesig = NULL, *nsecsig = NULL;
dns_typepair_t sigpair;
@@ -3536,7 +3525,7 @@ found:
sigpair = DNS_SIGTYPEPAIR(type);
empty_node = true;
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
/*
* Look for an active, extant rdataset.
@@ -4044,12 +4033,13 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
qpz_version_t *version = (qpz_version_t *)qrditer->common.version;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = qpzone_get_lock(node);
dns_slabheader_t *found = NULL;
dns_slabtop_t *top = NULL;
qrditer->currenttop = NULL;
qrditer->current = NULL;
NODE_RDLOCK(nlock, &nlocktype);
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *header = top->header;
while (header != NULL &&
(IGNORE(header) || header->serial > version->serial))
@@ -4058,17 +4048,15 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
}
if (header != NULL && EXISTS(header)) {
found = header;
qrditer->currenttop = top;
qrditer->current = header;
break;
}
}
NODE_UNLOCK(nlock, &nlocktype);
qrditer->currenttop = top;
qrditer->current = found;
if (top == NULL) {
if (qrditer->currenttop == NULL) {
return ISC_R_NOMORE;
}
@@ -4082,19 +4070,21 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
qpz_version_t *version = (qpz_version_t *)qrditer->common.version;
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
isc_rwlock_t *nlock = qpzone_get_lock(node);
dns_slabtop_t *top = qrditer->currenttop;
dns_slabheader_t *found = NULL;
dns_slabtop_t *next = NULL;
if (top == NULL) {
if (qrditer->currenttop == NULL) {
return ISC_R_NOMORE;
}
next = qrditer->currenttop->next;
qrditer->currenttop = NULL;
qrditer->current = NULL;
NODE_RDLOCK(nlock, &nlocktype);
/*
* Find the start of the header chain for the next type.
*/
for (top = top->next; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, next) {
dns_slabheader_t *header = top->header;
while (header != NULL &&
(IGNORE(header) || header->serial > version->serial))
@@ -4103,17 +4093,15 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
}
if (header != NULL && EXISTS(header)) {
found = header;
qrditer->currenttop = top;
qrditer->current = header;
break;
}
}
NODE_UNLOCK(nlock, &nlocktype);
qrditer->currenttop = top;
qrditer->current = found;
if (top == NULL) {
if (qrditer->currenttop == NULL) {
return ISC_R_NOMORE;
}
@@ -4837,7 +4825,7 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
qpz_version_t *version = (qpz_version_t *)dbversion;
dns_fixedname_t fname;
dns_name_t *nodename = dns_fixedname_initname(&fname);
dns_slabtop_t *top = NULL;
dns_slabtop_t *foundtop = NULL;
dns_slabheader_t *newheader = NULL;
dns_slabheader_t *subresult = NULL;
isc_region_t region;
@@ -4881,8 +4869,9 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
NODE_WRLOCK(nlock, &nlocktype);
changed = add_changed(qpdb, newheader, version DNS__DB_FLARG_PASS);
for (top = node->data; top != NULL; top = top->next) {
DNS_SLABTOP_FOREACH(top, node->data) {
if (top->typepair == newheader->typepair) {
foundtop = top;
break;
}
}
@@ -4892,8 +4881,8 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
* data. We skip over them.
*/
dns_slabheader_t *header = NULL;
if (top != NULL) {
header = top->header;
if (foundtop != NULL) {
header = foundtop->header;
while (header != NULL && IGNORE(header)) {
header = header->down;
}
@@ -4912,7 +4901,7 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
result = dns_rdataslab_subtract(
header, newheader, qpdb->common.mctx,
qpdb->common.rdclass,
DNS_TYPEPAIR_TYPE(top->typepair), flags,
DNS_TYPEPAIR_TYPE(foundtop->typepair), flags,
&subresult);
}
if (result == ISC_R_SUCCESS) {
@@ -4949,7 +4938,7 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
newheader = dns_slabheader_new(db->mctx,
(dns_dbnode_t *)node);
newheader->ttl = 0;
newheader->typepair = top->typepair;
newheader->typepair = foundtop->typepair;
atomic_init(&newheader->attributes,
DNS_SLABHEADERATTR_NONEXISTENT);
newheader->serial = version->serial;
@@ -4961,13 +4950,13 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
/*
* If we're here, we want to link newheader at the top.
*/
INSIST(version->serial >= top->header->serial);
INSIST(version->serial >= foundtop->header->serial);
maybe_update_recordsandsize(false, version, header,
nodename->length);
newheader->top = top;
newheader->down = top->header;
top->header = newheader;
newheader->top = foundtop;
newheader->down = foundtop->header;
foundtop->header = newheader;
node->dirty = true;
changed->dirty = true;
@@ -5433,11 +5422,7 @@ static dns_dbnode_methods_t qpznode_methods = (dns_dbnode_methods_t){
static void
destroy_qpznode(qpznode_t *node) {
dns_slabtop_t *top = NULL, *top_next = NULL;
for (top = node->data; top != NULL; top = top_next) {
top_next = top->next;
DNS_SLABTOP_FOREACH(top, node->data) {
dns_slabheader_t *down = NULL, *down_next = NULL;
for (down = top->header; down != NULL; down = down_next) {
down_next = down->down;