From: Evan Hunt Date: Sat, 8 Feb 2025 05:06:34 +0000 (-0800) Subject: initialize header in dns_rdataslab_fromrdataset() X-Git-Tag: ondrej/lock-free-qpzone-reads-v1~47^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82edec67a58afc837bf6b7ff62737faf931102e5;p=thirdparty%2Fbind9.git initialize header in dns_rdataslab_fromrdataset() when dns_rdataslab_fromrdataset() is run, in addition to allocating space for a slab header, it also partially initializes it, setting the type match rdataset->type and rdataset->covers, the trust to rdataset->trust, and the TTL to rdataset->ttl. --- diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h index 82f2a426b18..b2886871097 100644 --- a/lib/dns/include/dns/rdataslab.h +++ b/lib/dns/include/dns/rdataslab.h @@ -183,7 +183,11 @@ dns_rdataslab_raw_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, * * The dns_rdataslab_raw_fromrdataset() function allocates and fills only * the memory needed for a raw slab. dns_rdataslab_fromrdataset() also - * allocates space for a dns_slabheader object. + * allocates space for a dns_slabheader object, and partially initializes + * it, setting the type, trust, and TTL fields to match rdataset->type, + * rdataset->covers, rdataset->trust, and rdataset->ttl. (Note that the + * last field needs to be overridden when used in the cache database, + * since cache headers use an expire time instead of a TTL.) * * Requires: *\li 'rdataset' is valid. diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index b25bf45b6e1..78c5476535c 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -3201,18 +3201,20 @@ qpcache_addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdataset_getownercase(rdataset, name); newheader = (dns_slabheader_t *)region.base; - *newheader = (dns_slabheader_t){ - .type = DNS_TYPEPAIR_VALUE(rdataset->type, rdataset->covers), - .trust = rdataset->trust, - .last_used = now, - .node = (dns_dbnode_t *)qpnode, - }; - dns_slabheader_reset(newheader, db, node); + + newheader->last_used = now; + + /* + * By default, dns_rdataslab_fromrdataset() sets newheader->ttl + * to the rdataset TTL. In the case of the cache, that's wrong; + * we need it to be set to the expire time instead. + */ setttl(newheader, rdataset->ttl + now); if (rdataset->ttl == 0U) { DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_ZEROTTL); } + atomic_init(&newheader->count, atomic_fetch_add_relaxed(&init_count, 1)); if ((rdataset->attributes & DNS_RDATASETATTR_PREFETCH) != 0) { diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index db5f6a0727e..8b3d67c705d 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -2252,16 +2252,13 @@ loading_addrdataset(void *arg, const dns_name_t *name, } newheader = (dns_slabheader_t *)region.base; - *newheader = (dns_slabheader_t){ - .type = DNS_TYPEPAIR_VALUE(rdataset->type, rdataset->covers), - .ttl = rdataset->ttl, - .trust = rdataset->trust, - .node = (dns_dbnode_t *)node, - .serial = 1, - .count = 1, - }; - dns_slabheader_reset(newheader, (dns_db_t *)qpdb, (dns_dbnode_t *)node); + + newheader->ttl = rdataset->ttl; + newheader->trust = rdataset->trust; + newheader->serial = 1; + newheader->count = 1; + dns_slabheader_setownercase(newheader, name); if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { @@ -4737,17 +4734,12 @@ qpzone_addrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_rdataset_getownercase(rdataset, name); newheader = (dns_slabheader_t *)region.base; - *newheader = (dns_slabheader_t){ - .type = DNS_TYPEPAIR_VALUE(rdataset->type, rdataset->covers), - .trust = rdataset->trust, - .node = (dns_dbnode_t *)node, - }; - dns_slabheader_reset(newheader, db, (dns_dbnode_t *)node); newheader->ttl = rdataset->ttl; if (rdataset->ttl == 0U) { DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_ZEROTTL); } + atomic_init(&newheader->count, atomic_fetch_add_relaxed(&init_count, 1)); @@ -4860,26 +4852,16 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode, newheader = (dns_slabheader_t *)region.base; dns_slabheader_reset(newheader, db, (dns_dbnode_t *)node); newheader->ttl = rdataset->ttl; - newheader->type = DNS_TYPEPAIR_VALUE(rdataset->type, rdataset->covers); atomic_init(&newheader->attributes, 0); newheader->serial = version->serial; - newheader->trust = 0; - newheader->noqname = NULL; - newheader->closest = NULL; atomic_init(&newheader->count, atomic_fetch_add_relaxed(&init_count, 1)); - newheader->last_used = 0; - newheader->node = (dns_dbnode_t *)node; - newheader->db = (dns_db_t *)qpdb; if ((rdataset->attributes & DNS_RDATASETATTR_RESIGN) != 0) { DNS_SLABHEADER_SETATTR(newheader, DNS_SLABHEADERATTR_RESIGN); newheader->resign = (isc_stdtime_t)(dns_time64_from32(rdataset->resign) >> 1); newheader->resign_lsb = rdataset->resign & 0x1; - } else { - newheader->resign = 0; - newheader->resign_lsb = 0; } nlock = &qpdb->buckets[node->locknum].lock; diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index 14305914051..c316fe5dd6c 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -302,7 +302,22 @@ free_rdatas: isc_result_t dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, isc_region_t *region, uint32_t maxrrperset) { - return makeslab(rdataset, mctx, region, maxrrperset, false); + isc_result_t result; + + result = makeslab(rdataset, mctx, region, maxrrperset, false); + if (result == ISC_R_SUCCESS) { + dns_slabheader_t *new = (dns_slabheader_t *)region->base; + + *new = (dns_slabheader_t){ + .type = DNS_TYPEPAIR_VALUE(rdataset->type, + rdataset->covers), + .trust = rdataset->trust, + .ttl = rdataset->ttl, + .link = ISC_LINK_INITIALIZER, + }; + } + + return result; } isc_result_t