static dns_slabheader_t *
first_header(dns_slabtop_t *top) {
- return top->header;
+ dns_slabheader_t *header = NULL;
+ cds_list_for_each_entry(header, &top->headers, headers_link) {
+ return header;
+ }
+ return NULL;
+}
+
+static dns_slabheader_t *
+next_header(dns_slabheader_t *header) {
+ return cds_list_entry((header)->headers_link.next, dns_slabheader_t,
+ headers_link);
}
static dns_slabheader_t *
static void
clean_cache_headers(dns_slabtop_t *top) {
- if (top->header == NULL) {
+ dns_slabheader_t *parent = first_header(top);
+ if (parent == NULL) {
return;
}
- dns_slabheader_t *header = top->header, *header_down = NULL;
- for (header = header->down; header != NULL; header = header_down) {
- header_down = header->down;
+ dns_slabheader_t *header = next_header(parent), *header_next = NULL;
+ cds_list_for_each_entry_safe_from(header, header_next, &top->headers,
+ headers_link) {
+ cds_list_del(&header->headers_link);
dns_slabheader_destroy(&header);
}
- top->header->down = NULL;
}
static void
* If current top header is nonexistent, ancient, or stale
* and we are not keeping stale, we can clean it up too.
*/
- if (!EXISTS(top->header) || ANCIENT(top->header) ||
- (STALE(top->header) && !KEEPSTALE(qpdb)))
+ dns_slabheader_t *header = first_header(top);
+ if (header == NULL) {
+ continue;
+ }
+
+ if (!EXISTS(header) || ANCIENT(header) ||
+ (STALE(header) && !KEEPSTALE(qpdb)))
{
- dns_slabheader_destroy(&top->header);
+ cds_list_del(&header->headers_link);
+ dns_slabheader_destroy(&header);
}
/*
* If current slabtop is empty, we can clean it up.
*/
- if (top->header == NULL) {
+ if (header == NULL) {
cds_list_del(&top->types_link);
if (ISC_LINK_LINKED(top, link)) {
}
}
- node->dirty = 0;
+ node->dirty = false;
}
/*
if (top->typepair == newheader->typepair) {
INSIST(oldheader == NULL);
- oldheader = top->header;
+ oldheader = first_header(top);
}
if (sigpair != dns_rdatatype_none && top->typepair == sigpair) {
INSIST(oldsigheader == NULL);
- oldsigheader = top->header;
+ oldsigheader = first_header(top);
}
}
return DNS_R_UNCHANGED;
}
- oldheader->top->header = newheader;
newheader->top = oldheader->top;
- newheader->down = oldheader;
+ cds_list_add(&newheader->headers_link,
+ &oldheader->top->headers);
ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve,
oldheader->top, link);
return DNS_R_UNCHANGED;
} else {
/* No rdatasets of the given type exist at the node. */
- INSIST(newheader->down == NULL);
-
dns_slabtop_t *newtop = dns_slabtop_new(
((dns_db_t *)qpdb)->mctx, newheader->typepair);
- newtop->header = newheader;
newheader->top = newtop;
+ cds_list_add(&newheader->headers_link, &newtop->headers);
+
qpcache_miss(qpdb, newheader, &nlocktype,
&tlocktype DNS__DB_FLARG_PASS);
qpcache_t *qpdb = qpnode->qpdb;
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;
- dns_slabheader_destroy(&down);
+ dns_slabheader_t *header = NULL, *header_next = NULL;
+ cds_list_for_each_entry_safe(header, header_next, &top->headers,
+ headers_link)
+ {
+ cds_list_del(&header->headers_link);
+ dns_slabheader_destroy(&header);
}
- top->header = NULL;
if (ISC_LINK_LINKED(top, link)) {
ISC_SIEVE_UNLINK(qpdb->buckets[qpnode->locknum].sieve,
qpznode_erefs_increment(node DNS__DB_FLARG_PASS);
}
+static dns_slabheader_t *
+first_header(dns_slabtop_t *top) {
+ dns_slabheader_t *header = NULL;
+ cds_list_for_each_entry(header, &top->headers, headers_link) {
+ return header;
+ }
+ return NULL;
+}
+
+static dns_slabheader_t *
+next_header(dns_slabheader_t *header) {
+ return cds_list_entry((header)->headers_link.next, dns_slabheader_t,
+ headers_link);
+}
+
+static dns_slabheader_t *
+first_existing_header(dns_slabtop_t *top, uint32_t serial) {
+ dns_slabheader_t *header = NULL;
+ cds_list_for_each_entry(header, &top->headers, headers_link) {
+ if (header->serial <= serial && !IGNORE(header)) {
+ if (EXISTS(header)) {
+ return header;
+ }
+ break;
+ }
+ }
+ return NULL;
+}
+
static void
clean_multiple_headers(dns_slabtop_t *top) {
- dns_slabheader_t *parent = top->header;
- dns_slabheader_t *header = NULL, *header_down = NULL;
+ dns_slabheader_t *parent = first_header(top);
+ if (parent == NULL) {
+ return;
+ }
- for (header = parent->down; header != NULL; header = header_down) {
- header_down = header->down;
+ dns_slabheader_t *header = next_header(parent), *header_next = NULL;
+ cds_list_for_each_entry_safe_from(header, header_next, &top->headers,
+ headers_link) {
INSIST(header->serial <= parent->serial);
if (header->serial == parent->serial || IGNORE(header)) {
- parent->down = header->down;
+ cds_list_del(&header->headers_link);
dns_slabheader_destroy(&header);
} else {
parent = header;
static void
check_top_header(dns_slabtop_t *top) {
- dns_slabheader_t *header = top->header;
- if (IGNORE(header)) {
- top->header = header->down;
+ dns_slabheader_t *header = first_header(top);
+ if (header != NULL && IGNORE(header)) {
+ cds_list_del(&header->headers_link);
dns_slabheader_destroy(&header);
}
}
static bool
clean_multiple_versions(dns_slabtop_t *top, uint32_t least_serial) {
- dns_slabheader_t *parent = top->header;
- dns_slabheader_t *header = NULL, *header_down = NULL;
- bool multiple = false;
+ dns_slabheader_t *parent = first_header(top);
+ if (parent == NULL) {
+ return false;
+ }
- for (header = parent->down; header != NULL; header = header_down) {
- header_down = header->down;
+ bool multiple = false;
+ dns_slabheader_t *header = next_header(parent), *header_next = NULL;
+ cds_list_for_each_entry_safe_from(header, header_next, &top->headers,
+ headers_link) {
if (header->serial < least_serial) {
- parent->down = header->down;
+ cds_list_del(&header->headers_link);
dns_slabheader_destroy(&header);
} else {
multiple = true;
REQUIRE(least_serial != 0);
DNS_SLABTOP_FOREACH(top, node->data) {
- INSIST(top->header != NULL);
-
/*
* First, we clean up any instances of multiple rdatasets
* with the same serial number, or that have the IGNORE
*/
check_top_header(top);
- if (top->header == NULL) {
+ if (first_header(top) == NULL) {
cds_list_del(&top->types_link);
dns_slabtop_destroy(node->mctx, &top);
} else {
}
}
-static dns_slabheader_t *
-first_header(dns_slabtop_t *top, uint32_t serial) {
- for (dns_slabheader_t *header = top->header; header != NULL;
- header = header->down)
- {
- if (header->serial <= serial && !IGNORE(header)) {
- return header;
- }
- }
-
- return NULL;
-}
-
-static dns_slabheader_t *
-first_existing_header(dns_slabtop_t *top, uint32_t serial) {
- dns_slabheader_t *header = first_header(top, serial);
- if (header != NULL && EXISTS(header)) {
- return header;
- }
- return NULL;
-}
-
static void
setnsec3parameters(dns_db_t *db, qpz_version_t *version) {
qpznode_t *node = NULL;
* will be cleaned up; until that time, they will be ignored.
*/
DNS_SLABTOP_FOREACH(top, node->data) {
- dns_slabheader_t *header = top->header;
-
- if (header->serial == serial) {
- DNS_SLABHEADER_SETATTR(header,
- DNS_SLABHEADERATTR_IGNORE);
- make_dirty = true;
- }
-
- for (header = header->down; header != NULL;
- header = header->down)
- {
+ dns_slabheader_t *header = NULL;
+ cds_list_for_each_entry(header, &top->headers, headers_link) {
if (header->serial == serial) {
DNS_SLABHEADER_SETATTR(
header, DNS_SLABHEADERATTR_IGNORE);
* IGNORE rdatasets between the top of the chain and the first real
* data. We skip over them.
*/
- dns_slabheader_t *header = NULL, *header_prev = NULL;
+ dns_slabheader_t *header = NULL;
if (foundtop != NULL) {
- header = foundtop->header;
- while (header != NULL && IGNORE(header)) {
- header_prev = header;
- header = header->down;
+ dns_slabheader_t *tmp = NULL;
+ cds_list_for_each_entry(tmp, &top->headers, headers_link) {
+ if (!IGNORE(tmp)) {
+ header = tmp;
+ break;
+ }
}
}
}
}
- INSIST(version->serial >= foundtop->header->serial);
+ INSIST(version->serial >= header->serial);
INSIST(foundtop->typepair == newheader->typepair);
if (loading) {
- newheader->down = NULL;
if (RESIGN(newheader)) {
resigninsert(newheader);
/* resigndelete not needed here */
* loading, we MUST clean up 'header' now.
*/
newheader->top = foundtop;
- foundtop->header = newheader;
+ cds_list_del(&header->headers_link);
+ cds_list_add(&newheader->headers_link,
+ &foundtop->headers);
maybe_update_recordsandsize(false, version, header,
nodename->length);
header DNS__DB_FLARG_PASS);
}
- if (header_prev != NULL) {
- header_prev->down = newheader;
- } else {
- foundtop->header = newheader;
- }
-
newheader->top = foundtop;
- newheader->down = header;
+ cds_list_add(&newheader->headers_link,
+ &foundtop->headers);
node->dirty = true;
if (changed != NULL) {
* we INSIST on it.
*/
INSIST(!loading);
- INSIST(version->serial >= foundtop->header->serial);
+
newheader->top = foundtop;
- newheader->down = foundtop->header;
- foundtop->header = newheader;
+ cds_list_add(&newheader->headers_link,
+ &foundtop->headers);
+
if (changed != NULL) {
changed->dirty = true;
}
node->mctx, newheader->typepair);
newheader->top = newtop;
- newtop->header = newheader;
+ cds_list_add(&newheader->headers_link,
+ &newtop->headers);
if (prio_type(newheader->typepair)) {
/* This is a priority type, prepend it */
newheader = (dns_slabheader_t *)region.base;
dns_slabheader_reset(newheader, (dns_dbnode_t *)node);
-
newheader->ttl = rdataset->ttl;
atomic_store(&newheader->trust, rdataset->trust);
newheader->serial = 1;
*/
dns_slabheader_t *header = NULL;
if (foundtop != NULL) {
- header = foundtop->header;
- while (header != NULL && IGNORE(header)) {
- header = header->down;
+ dns_slabheader_t *tmp = NULL;
+ cds_list_for_each_entry(tmp, &foundtop->headers, headers_link) {
+ if (!IGNORE(tmp)) {
+ header = tmp;
+ break;
+ }
}
}
if (header != NULL && EXISTS(header)) {
/*
* If we're here, we want to link newheader at the top.
*/
- INSIST(version->serial >= foundtop->header->serial);
maybe_update_recordsandsize(false, version, header,
nodename->length);
newheader->top = foundtop;
- newheader->down = foundtop->header;
- foundtop->header = newheader;
+ cds_list_add(&newheader->headers_link, &foundtop->headers);
node->dirty = true;
changed->dirty = true;
static void
destroy_qpznode(qpznode_t *node) {
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;
- dns_slabheader_destroy(&down);
+ dns_slabheader_t *header = NULL, *header_next = NULL;
+ cds_list_for_each_entry_safe(header, header_next, &top->headers,
+ headers_link)
+ {
+ cds_list_del(&header->headers_link);
+ dns_slabheader_destroy(&header);
}
- top->header = NULL;
dns_slabtop_destroy(node->mctx, &top);
}