From: Ondřej Surý Date: Thu, 21 Aug 2025 06:56:29 +0000 (+0200) Subject: Add DNS_SLABTOP_FOREACH macros X-Git-Tag: v9.21.12~14^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e3c0a2a0fdeb4eb567524785e8b8773933e5329c;p=thirdparty%2Fbind9.git Add DNS_SLABTOP_FOREACH macros Add foreach macros to iterate through the dns_slabtop_t single-linked lists. --- diff --git a/.clang-format b/.clang-format index b26764d5d02..bab1c2c0a23 100644 --- a/.clang-format +++ b/.clang-format @@ -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 diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h index a292b4acd35..8b6bd7ab041 100644 --- a/lib/dns/include/dns/rdataslab.h +++ b/lib/dns/include/dns/rdataslab.h @@ -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; diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index fa2cfae7ac1..70c88a67883 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -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; diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 247434d3ace..1c28adfb7d4 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -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;