mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 10:10:06 +00:00
chg: dev: Remove opportunistic node cleaning from qpzone
Currently, when releasing a qpznode after a read operation, we will check if the node is dirty due to a previous write, upgrade the lock to a write lock and perform a cleanup. An unintended side effect of this is that protecting a node by increasing the reference count must also protect its parent database. For the very common case where only one zone is configured, this is a non-trivial source of contention, as the same refcount will be hit by all threads. This MR removes the opportunistic cleaning and the database refcount, reducing contention. Cleaning will be done only on closeversion. Merge branch 'alessio/remove-opportunistic-node-cleaning' into 'main' See merge request isc-projects/bind9!10814
This commit is contained in:
commit
3a84604e23
152
lib/dns/qpzone.c
152
lib/dns/qpzone.c
@ -167,7 +167,6 @@ struct qpznode {
|
|||||||
DBNODE_FIELDS;
|
DBNODE_FIELDS;
|
||||||
|
|
||||||
qpz_heap_t *heap;
|
qpz_heap_t *heap;
|
||||||
qpzonedb_t *qpdb;
|
|
||||||
/*
|
/*
|
||||||
* 'erefs' counts external references held by a caller: for
|
* 'erefs' counts external references held by a caller: for
|
||||||
* example, it could be incremented by dns_db_findnode(),
|
* example, it could be incremented by dns_db_findnode(),
|
||||||
@ -222,7 +221,6 @@ struct qpzonedb {
|
|||||||
* reference is released. When in turn 'references' goes to zero,
|
* reference is released. When in turn 'references' goes to zero,
|
||||||
* the database is shut down and freed.
|
* the database is shut down and freed.
|
||||||
*/
|
*/
|
||||||
isc_refcount_t references;
|
|
||||||
|
|
||||||
qpznode_t *origin;
|
qpznode_t *origin;
|
||||||
qpznode_t *nsec_origin;
|
qpznode_t *nsec_origin;
|
||||||
@ -246,18 +244,6 @@ struct qpzonedb {
|
|||||||
dns_qpmulti_t *tree; /* QP trie for data storage */
|
dns_qpmulti_t *tree; /* QP trie for data storage */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef DNS_DB_NODETRACE
|
|
||||||
#define qpzonedb_ref(ptr) qpzonedb__ref(ptr, __func__, __FILE__, __LINE__)
|
|
||||||
#define qpzonedb_unref(ptr) qpzonedb__unref(ptr, __func__, __FILE__, __LINE__)
|
|
||||||
#define qpzonedb_attach(ptr, ptrp) \
|
|
||||||
qpzonedb__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
|
|
||||||
#define qpzonedb_detach(ptrp) \
|
|
||||||
qpzonedb__detach(ptrp, __func__, __FILE__, __LINE__)
|
|
||||||
ISC_REFCOUNT_STATIC_TRACE_DECL(qpzonedb);
|
|
||||||
#else
|
|
||||||
ISC_REFCOUNT_STATIC_DECL(qpzonedb);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
* Search Context
|
* Search Context
|
||||||
*/
|
*/
|
||||||
@ -541,7 +527,6 @@ free_db_rcu(struct rcu_head *rcu_head) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
isc_rwlock_destroy(&qpdb->lock);
|
isc_rwlock_destroy(&qpdb->lock);
|
||||||
isc_refcount_destroy(&qpdb->references);
|
|
||||||
isc_refcount_destroy(&qpdb->common.references);
|
isc_refcount_destroy(&qpdb->common.references);
|
||||||
|
|
||||||
qpdb->common.magic = 0;
|
qpdb->common.magic = 0;
|
||||||
@ -604,7 +589,7 @@ qpdb_destroy(dns_db_t *arg) {
|
|||||||
cleanup_gluelists(&qpdb->current_version->glue_stack);
|
cleanup_gluelists(&qpdb->current_version->glue_stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
qpzonedb_detach(&qpdb);
|
qpzone_destroy(qpdb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static qpz_heap_t *
|
static qpz_heap_t *
|
||||||
@ -662,7 +647,6 @@ new_qpznode(qpzonedb_t *qpdb, const dns_name_t *name, dns_namespace_t nspace) {
|
|||||||
.nspace = nspace,
|
.nspace = nspace,
|
||||||
.heap = qpdb->heap,
|
.heap = qpdb->heap,
|
||||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
.references = ISC_REFCOUNT_INITIALIZER(1),
|
||||||
.qpdb = qpdb,
|
|
||||||
.locknum = qpzone_get_locknum(),
|
.locknum = qpzone_get_locknum(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -714,7 +698,6 @@ dns__qpzone_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
.least_serial = 1,
|
.least_serial = 1,
|
||||||
.next_serial = 2,
|
.next_serial = 2,
|
||||||
.open_versions = ISC_LIST_INITIALIZER,
|
.open_versions = ISC_LIST_INITIALIZER,
|
||||||
.references = ISC_REFCOUNT_INITIALIZER(1),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
qpdb->common.methods = &qpdb_zonemethods;
|
qpdb->common.methods = &qpdb_zonemethods;
|
||||||
@ -811,7 +794,7 @@ dns__qpzone_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
|
|||||||
* qpznode_release() when we only need to increase the internal references.
|
* qpznode_release() when we only need to increase the internal references.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
qpznode_erefs_increment(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
|
qpznode_erefs_increment(qpznode_t *node DNS__DB_FLARG) {
|
||||||
uint_fast32_t refs = isc_refcount_increment0(&node->erefs);
|
uint_fast32_t refs = isc_refcount_increment0(&node->erefs);
|
||||||
#if DNS_DB_NODETRACE
|
#if DNS_DB_NODETRACE
|
||||||
fprintf(stderr, "incr:node:%s:%s:%u:%p->erefs = %" PRIuFAST32 "\n",
|
fprintf(stderr, "incr:node:%s:%s:%u:%p->erefs = %" PRIuFAST32 "\n",
|
||||||
@ -821,21 +804,18 @@ qpznode_erefs_increment(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
|
|||||||
if (refs > 0) {
|
if (refs > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpzonedb_ref(qpdb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qpznode_acquire(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
|
qpznode_acquire(qpznode_t *node DNS__DB_FLARG) {
|
||||||
qpznode_ref(node);
|
qpznode_ref(node);
|
||||||
qpznode_erefs_increment(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_erefs_increment(node DNS__DB_FLARG_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clean_zone_node(qpznode_t *node, uint32_t least_serial) {
|
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 = NULL, *top_prev = NULL, *top_next = NULL;
|
||||||
bool still_dirty = false;
|
bool still_dirty = false;
|
||||||
dns_db_t *db = (dns_db_t *)node->qpdb;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller must be holding the node lock.
|
* Caller must be holding the node lock.
|
||||||
@ -910,7 +890,7 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
|
|||||||
} else {
|
} else {
|
||||||
node->data = top->next;
|
node->data = top->next;
|
||||||
}
|
}
|
||||||
dns_slabtop_destroy(db->mctx, &top);
|
dns_slabtop_destroy(node->mctx, &top);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Note. The serial number of 'current' might be less
|
* Note. The serial number of 'current' might be less
|
||||||
@ -932,7 +912,7 @@ clean_zone_node(qpznode_t *node, uint32_t least_serial) {
|
|||||||
* as well, and return true. Otherwise return false.
|
* as well, and return true. Otherwise return false.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
qpznode_erefs_decrement(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
|
qpznode_erefs_decrement(qpznode_t *node DNS__DB_FLARG) {
|
||||||
uint_fast32_t refs = isc_refcount_decrement(&node->erefs);
|
uint_fast32_t refs = isc_refcount_decrement(&node->erefs);
|
||||||
|
|
||||||
#if DNS_DB_NODETRACE
|
#if DNS_DB_NODETRACE
|
||||||
@ -943,8 +923,6 @@ qpznode_erefs_decrement(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpzonedb_unref(qpdb);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -961,54 +939,31 @@ qpznode_erefs_decrement(qpzonedb_t *qpdb, qpznode_t *node DNS__DB_FLARG) {
|
|||||||
* if necessary, then decrements the internal reference counter as well.
|
* if necessary, then decrements the internal reference counter as well.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
qpznode_release(qpzonedb_t *qpdb, qpznode_t *node, uint32_t least_serial,
|
qpznode_release(qpznode_t *node, uint32_t least_serial,
|
||||||
isc_rwlocktype_t *nlocktypep DNS__DB_FLARG) {
|
isc_rwlocktype_t *nlocktypep DNS__DB_FLARG) {
|
||||||
REQUIRE(*nlocktypep != isc_rwlocktype_none);
|
REQUIRE(*nlocktypep != isc_rwlocktype_none);
|
||||||
|
|
||||||
if (!qpznode_erefs_decrement(qpdb, node DNS__DB_FLARG_PASS)) {
|
if (!qpznode_erefs_decrement(node DNS__DB_FLARG_PASS)) {
|
||||||
goto unref;
|
goto unref;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle easy and typical case first. */
|
/* Handle easy and typical case first. */
|
||||||
if (!node->dirty &&
|
if (!node->dirty && node->data != NULL) {
|
||||||
(node->data != NULL || node == qpdb->origin ||
|
|
||||||
node == qpdb->nsec_origin || node == qpdb->nsec3_origin))
|
|
||||||
{
|
|
||||||
goto unref;
|
goto unref;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*nlocktypep == isc_rwlocktype_read) {
|
if (node->dirty && least_serial > 0) {
|
||||||
/*
|
/*
|
||||||
* The external reference count went to zero and the node
|
* Only do node cleanup when called from closeversion.
|
||||||
* is dirty or has no data, so we might want to delete it.
|
* Closeversion, unlike other call sites, will provide the
|
||||||
* To do that, we'll need a write lock. If we don't already
|
* least_serial, and will hold a write lock instead of a read
|
||||||
* have one, we have to make sure nobody else has
|
* lock.
|
||||||
* acquired a reference in the meantime, so we increment
|
|
||||||
* erefs (but NOT references!), upgrade the node lock,
|
|
||||||
* decrement erefs again, and see if it's still zero.
|
|
||||||
*
|
*
|
||||||
* We can't really assume anything about the result code of
|
* This way we avoid having to protect the db by increasing
|
||||||
* erefs_increment. If another thread acquires reference it
|
* the db reference count, avoiding contention in single
|
||||||
* will be larger than 0, if it doesn't it is going to be 0.
|
* zone workloads.
|
||||||
*/
|
*/
|
||||||
isc_rwlock_t *nlock = qpzone_get_lock(node);
|
REQUIRE(*nlocktypep == isc_rwlocktype_write);
|
||||||
qpznode_erefs_increment(qpdb, node DNS__DB_FLARG_PASS);
|
|
||||||
NODE_FORCEUPGRADE(nlock, nlocktypep);
|
|
||||||
if (!qpznode_erefs_decrement(qpdb, node DNS__DB_FLARG_PASS)) {
|
|
||||||
goto unref;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node->dirty) {
|
|
||||||
if (least_serial == 0) {
|
|
||||||
/*
|
|
||||||
* Caller doesn't know the least serial.
|
|
||||||
* Get it.
|
|
||||||
*/
|
|
||||||
RWLOCK(&qpdb->lock, isc_rwlocktype_read);
|
|
||||||
least_serial = qpdb->least_serial;
|
|
||||||
RWUNLOCK(&qpdb->lock, isc_rwlocktype_read);
|
|
||||||
}
|
|
||||||
clean_zone_node(node, least_serial);
|
clean_zone_node(node, least_serial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1023,7 +978,7 @@ bindrdataset(qpzonedb_t *qpdb, qpznode_t *node, dns_slabheader_t *header,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
INSIST(rdataset->methods == NULL); /* We must be disassociated. */
|
INSIST(rdataset->methods == NULL); /* We must be disassociated. */
|
||||||
|
|
||||||
@ -1308,7 +1263,7 @@ resigndelete(qpzonedb_t *qpdb ISC_ATTR_UNUSED, qpz_version_t *version,
|
|||||||
UNLOCK(get_heap_lock(header));
|
UNLOCK(get_heap_lock(header));
|
||||||
|
|
||||||
header->heap_index = 0;
|
header->heap_index = 0;
|
||||||
qpznode_acquire(qpdb, HEADERNODE(header) DNS__DB_FLARG_PASS);
|
qpznode_acquire(HEADERNODE(header) DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
qpz_resigned_t *resigned = isc_mem_get(((dns_db_t *)qpdb)->mctx,
|
qpz_resigned_t *resigned = isc_mem_get(((dns_db_t *)qpdb)->mctx,
|
||||||
sizeof(*resigned));
|
sizeof(*resigned));
|
||||||
@ -1559,7 +1514,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp,
|
|||||||
if (rollback && !IGNORE(header)) {
|
if (rollback && !IGNORE(header)) {
|
||||||
resigninsert(header);
|
resigninsert(header);
|
||||||
}
|
}
|
||||||
qpznode_release(qpdb, HEADERNODE(header), least_serial,
|
qpznode_release(HEADERNODE(header), least_serial,
|
||||||
&nlocktype DNS__DB_FLARG_PASS);
|
&nlocktype DNS__DB_FLARG_PASS);
|
||||||
NODE_UNLOCK(nlock, &nlocktype);
|
NODE_UNLOCK(nlock, &nlocktype);
|
||||||
}
|
}
|
||||||
@ -1580,7 +1535,7 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp,
|
|||||||
if (rollback) {
|
if (rollback) {
|
||||||
rollback_node(node, serial);
|
rollback_node(node, serial);
|
||||||
}
|
}
|
||||||
qpznode_release(qpdb, node, least_serial,
|
qpznode_release(node, least_serial,
|
||||||
&nlocktype DNS__DB_FILELINE);
|
&nlocktype DNS__DB_FILELINE);
|
||||||
|
|
||||||
NODE_UNLOCK(nlock, &nlocktype);
|
NODE_UNLOCK(nlock, &nlocktype);
|
||||||
@ -1816,10 +1771,10 @@ cname_and_other(qpznode_t *node, uint32_t serial) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static qpz_changed_t *
|
static qpz_changed_t *
|
||||||
add_changed(dns_slabheader_t *header, qpz_version_t *version DNS__DB_FLARG) {
|
add_changed(qpzonedb_t *qpdb, dns_slabheader_t *header,
|
||||||
|
qpz_version_t *version DNS__DB_FLARG) {
|
||||||
qpz_changed_t *changed = NULL;
|
qpz_changed_t *changed = NULL;
|
||||||
qpznode_t *node = HEADERNODE(header);
|
qpznode_t *node = HEADERNODE(header);
|
||||||
qpzonedb_t *qpdb = node->qpdb;
|
|
||||||
|
|
||||||
changed = isc_mem_get(qpdb->common.mctx, sizeof(*changed));
|
changed = isc_mem_get(qpdb->common.mctx, sizeof(*changed));
|
||||||
|
|
||||||
@ -1828,7 +1783,7 @@ add_changed(dns_slabheader_t *header, qpz_version_t *version DNS__DB_FLARG) {
|
|||||||
|
|
||||||
*changed = (qpz_changed_t){ .node = node };
|
*changed = (qpz_changed_t){ .node = node };
|
||||||
ISC_LIST_INITANDAPPEND(version->changed_list, changed, link);
|
ISC_LIST_INITANDAPPEND(version->changed_list, changed, link);
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
RWUNLOCK(&qpdb->lock, isc_rwlocktype_write);
|
RWUNLOCK(&qpdb->lock, isc_rwlocktype_write);
|
||||||
|
|
||||||
return changed;
|
return changed;
|
||||||
@ -1882,7 +1837,8 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
|
|||||||
* being made to this node, because it's harmless and
|
* being made to this node, because it's harmless and
|
||||||
* simplifies the code.
|
* simplifies the code.
|
||||||
*/
|
*/
|
||||||
changed = add_changed(newheader, version DNS__DB_FLARG_PASS);
|
changed = add_changed(qpdb, newheader,
|
||||||
|
version DNS__DB_FLARG_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
ntypes = 0;
|
ntypes = 0;
|
||||||
@ -2067,7 +2023,7 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dns_slabtop_t *newtop = dns_slabtop_new(
|
dns_slabtop_t *newtop = dns_slabtop_new(
|
||||||
((dns_db_t *)qpdb)->mctx, newheader->typepair);
|
node->mctx, newheader->typepair);
|
||||||
|
|
||||||
newheader->top = newtop;
|
newheader->top = newtop;
|
||||||
newtop->header = newheader;
|
newtop->header = newheader;
|
||||||
@ -2569,7 +2525,7 @@ findnodeintree(qpzonedb_t *qpdb, const dns_name_t *name, bool create,
|
|||||||
|
|
||||||
INSIST(node->nspace == DNS_DBNAMESPACE_NSEC3 || !nsec3);
|
INSIST(node->nspace == DNS_DBNAMESPACE_NSEC3 || !nsec3);
|
||||||
|
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
dns_qp_compact(qp, DNS_QPGC_MAYBE);
|
dns_qp_compact(qp, DNS_QPGC_MAYBE);
|
||||||
@ -3171,7 +3127,6 @@ again:
|
|||||||
dns_name_copy(name, foundname);
|
dns_name_copy(name, foundname);
|
||||||
if (nodep != NULL) {
|
if (nodep != NULL) {
|
||||||
qpznode_acquire(
|
qpznode_acquire(
|
||||||
search->qpdb,
|
|
||||||
node DNS__DB_FLARG_PASS);
|
node DNS__DB_FLARG_PASS);
|
||||||
*nodep = (dns_dbnode_t *)node;
|
*nodep = (dns_dbnode_t *)node;
|
||||||
}
|
}
|
||||||
@ -3316,7 +3271,7 @@ qpzone_check_zonecut(qpznode_t *node, void *arg DNS__DB_FLARG) {
|
|||||||
* We increment the reference count on node to ensure that
|
* We increment the reference count on node to ensure that
|
||||||
* search->zonecut_header will still be valid later.
|
* search->zonecut_header will still be valid later.
|
||||||
*/
|
*/
|
||||||
qpznode_acquire(search->qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
search->zonecut = node;
|
search->zonecut = node;
|
||||||
search->zonecut_header = found;
|
search->zonecut_header = found;
|
||||||
search->need_cleanup = true;
|
search->need_cleanup = true;
|
||||||
@ -3618,8 +3573,7 @@ found:
|
|||||||
* ensure that search->zonecut_header will
|
* ensure that search->zonecut_header will
|
||||||
* still be valid later.
|
* still be valid later.
|
||||||
*/
|
*/
|
||||||
qpznode_acquire(search.qpdb,
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
node DNS__DB_FLARG_PASS);
|
|
||||||
search.zonecut = node;
|
search.zonecut = node;
|
||||||
search.zonecut_header = header;
|
search.zonecut_header = header;
|
||||||
search.zonecut_sigheader = NULL;
|
search.zonecut_sigheader = NULL;
|
||||||
@ -3809,7 +3763,7 @@ found:
|
|||||||
goto tree_exit;
|
goto tree_exit;
|
||||||
}
|
}
|
||||||
if (nodep != NULL) {
|
if (nodep != NULL) {
|
||||||
qpznode_acquire(search.qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
*nodep = (dns_dbnode_t *)node;
|
*nodep = (dns_dbnode_t *)node;
|
||||||
}
|
}
|
||||||
if (search.version->secure && !search.version->havensec3) {
|
if (search.version->secure && !search.version->havensec3) {
|
||||||
@ -3872,7 +3826,7 @@ found:
|
|||||||
|
|
||||||
if (nodep != NULL) {
|
if (nodep != NULL) {
|
||||||
if (!at_zonecut) {
|
if (!at_zonecut) {
|
||||||
qpznode_acquire(search.qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
} else {
|
} else {
|
||||||
search.need_cleanup = false;
|
search.need_cleanup = false;
|
||||||
}
|
}
|
||||||
@ -3908,8 +3862,7 @@ tree_exit:
|
|||||||
nlock = qpzone_get_lock(node);
|
nlock = qpzone_get_lock(node);
|
||||||
|
|
||||||
NODE_RDLOCK(nlock, &nlocktype);
|
NODE_RDLOCK(nlock, &nlocktype);
|
||||||
qpznode_release(search.qpdb, node, 0,
|
qpznode_release(node, 0, &nlocktype DNS__DB_FLARG_PASS);
|
||||||
&nlocktype DNS__DB_FLARG_PASS);
|
|
||||||
NODE_UNLOCK(nlock, &nlocktype);
|
NODE_UNLOCK(nlock, &nlocktype);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3949,7 +3902,7 @@ qpzone_allrdatasets(dns_db_t *db, dns_dbnode_t *dbnode,
|
|||||||
.common.magic = DNS_RDATASETITER_MAGIC,
|
.common.magic = DNS_RDATASETITER_MAGIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
*iteratorp = (dns_rdatasetiter_t *)iterator;
|
*iteratorp = (dns_rdatasetiter_t *)iterator;
|
||||||
return ISC_R_SUCCESS;
|
return ISC_R_SUCCESS;
|
||||||
@ -3958,12 +3911,10 @@ qpzone_allrdatasets(dns_db_t *db, dns_dbnode_t *dbnode,
|
|||||||
static void
|
static void
|
||||||
qpzone_attachnode(dns_dbnode_t *source, dns_dbnode_t **targetp DNS__DB_FLARG) {
|
qpzone_attachnode(dns_dbnode_t *source, dns_dbnode_t **targetp DNS__DB_FLARG) {
|
||||||
qpznode_t *node = (qpznode_t *)source;
|
qpznode_t *node = (qpznode_t *)source;
|
||||||
qpzonedb_t *qpdb = node->qpdb;
|
|
||||||
|
|
||||||
REQUIRE(VALID_QPZONE(qpdb));
|
|
||||||
REQUIRE(targetp != NULL && *targetp == NULL);
|
REQUIRE(targetp != NULL && *targetp == NULL);
|
||||||
|
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
*targetp = source;
|
*targetp = source;
|
||||||
}
|
}
|
||||||
@ -3973,14 +3924,11 @@ qpzone_detachnode(dns_dbnode_t **nodep DNS__DB_FLARG) {
|
|||||||
qpznode_t *node = NULL;
|
qpznode_t *node = NULL;
|
||||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||||
isc_rwlock_t *nlock = NULL;
|
isc_rwlock_t *nlock = NULL;
|
||||||
qpzonedb_t *qpdb;
|
|
||||||
|
|
||||||
REQUIRE(nodep != NULL && *nodep != NULL);
|
REQUIRE(nodep != NULL && *nodep != NULL);
|
||||||
|
|
||||||
node = (qpznode_t *)(*nodep);
|
node = (qpznode_t *)(*nodep);
|
||||||
qpdb = node->qpdb;
|
|
||||||
|
|
||||||
REQUIRE(VALID_QPZONE(qpdb));
|
|
||||||
*nodep = NULL;
|
*nodep = NULL;
|
||||||
nlock = qpzone_get_lock(node);
|
nlock = qpzone_get_lock(node);
|
||||||
|
|
||||||
@ -3991,15 +3939,11 @@ qpzone_detachnode(dns_dbnode_t **nodep DNS__DB_FLARG) {
|
|||||||
* NODE_LOCK is locked.
|
* NODE_LOCK is locked.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
qpzonedb_ref(qpdb);
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
NODE_RDLOCK(nlock, &nlocktype);
|
NODE_RDLOCK(nlock, &nlocktype);
|
||||||
qpznode_release(qpdb, node, 0, &nlocktype DNS__DB_FLARG_PASS);
|
qpznode_release(node, 0, &nlocktype DNS__DB_FLARG_PASS);
|
||||||
NODE_UNLOCK(nlock, &nlocktype);
|
NODE_UNLOCK(nlock, &nlocktype);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
qpzonedb_unref(qpdb);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
@ -4043,7 +3987,7 @@ getoriginnode(dns_db_t *db, dns_dbnode_t **nodep DNS__DB_FLARG) {
|
|||||||
|
|
||||||
/* Note that the access to the origin node doesn't require a DB lock */
|
/* Note that the access to the origin node doesn't require a DB lock */
|
||||||
INSIST(qpdb->origin != NULL);
|
INSIST(qpdb->origin != NULL);
|
||||||
qpznode_acquire(qpdb, qpdb->origin DNS__DB_FLARG_PASS);
|
qpznode_acquire(qpdb->origin DNS__DB_FLARG_PASS);
|
||||||
*nodep = (dns_dbnode_t *)qpdb->origin;
|
*nodep = (dns_dbnode_t *)qpdb->origin;
|
||||||
|
|
||||||
return ISC_R_SUCCESS;
|
return ISC_R_SUCCESS;
|
||||||
@ -4203,19 +4147,17 @@ rdatasetiter_current(dns_rdatasetiter_t *iterator,
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
reference_iter_node(qpdb_dbiterator_t *iter DNS__DB_FLARG) {
|
reference_iter_node(qpdb_dbiterator_t *iter DNS__DB_FLARG) {
|
||||||
qpzonedb_t *qpdb = (qpzonedb_t *)iter->common.db;
|
|
||||||
qpznode_t *node = iter->node;
|
qpznode_t *node = iter->node;
|
||||||
|
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dereference_iter_node(qpdb_dbiterator_t *iter DNS__DB_FLARG) {
|
dereference_iter_node(qpdb_dbiterator_t *iter DNS__DB_FLARG) {
|
||||||
qpzonedb_t *qpdb = (qpzonedb_t *)iter->common.db;
|
|
||||||
qpznode_t *node = iter->node;
|
qpznode_t *node = iter->node;
|
||||||
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
isc_rwlocktype_t nlocktype = isc_rwlocktype_none;
|
||||||
isc_rwlock_t *nlock = NULL;
|
isc_rwlock_t *nlock = NULL;
|
||||||
@ -4228,7 +4170,7 @@ dereference_iter_node(qpdb_dbiterator_t *iter DNS__DB_FLARG) {
|
|||||||
nlock = qpzone_get_lock(node);
|
nlock = qpzone_get_lock(node);
|
||||||
|
|
||||||
NODE_RDLOCK(nlock, &nlocktype);
|
NODE_RDLOCK(nlock, &nlocktype);
|
||||||
qpznode_release(qpdb, node, 0, &nlocktype DNS__DB_FLARG_PASS);
|
qpznode_release(node, 0, &nlocktype DNS__DB_FLARG_PASS);
|
||||||
NODE_UNLOCK(nlock, &nlocktype);
|
NODE_UNLOCK(nlock, &nlocktype);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4675,7 +4617,6 @@ dbiterator_next(dns_dbiterator_t *iterator DNS__DB_FLARG) {
|
|||||||
static isc_result_t
|
static isc_result_t
|
||||||
dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
|
dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
|
||||||
dns_name_t *name DNS__DB_FLARG) {
|
dns_name_t *name DNS__DB_FLARG) {
|
||||||
qpzonedb_t *qpdb = (qpzonedb_t *)iterator->db;
|
|
||||||
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
|
qpdb_dbiterator_t *qpdbiter = (qpdb_dbiterator_t *)iterator;
|
||||||
qpznode_t *node = qpdbiter->node;
|
qpznode_t *node = qpdbiter->node;
|
||||||
|
|
||||||
@ -4686,7 +4627,7 @@ dbiterator_current(dns_dbiterator_t *iterator, dns_dbnode_t **nodep,
|
|||||||
dns_name_copy(&qpdbiter->node->name, name);
|
dns_name_copy(&qpdbiter->node->name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
qpznode_acquire(qpdb, node DNS__DB_FLARG_PASS);
|
qpznode_acquire(node DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
*nodep = (dns_dbnode_t *)qpdbiter->node;
|
*nodep = (dns_dbnode_t *)qpdbiter->node;
|
||||||
|
|
||||||
@ -4942,7 +4883,7 @@ qpzone_subtractrdataset(dns_db_t *db, dns_dbnode_t *dbnode,
|
|||||||
nlock = qpzone_get_lock(node);
|
nlock = qpzone_get_lock(node);
|
||||||
NODE_WRLOCK(nlock, &nlocktype);
|
NODE_WRLOCK(nlock, &nlocktype);
|
||||||
|
|
||||||
changed = add_changed(newheader, version DNS__DB_FLARG_PASS);
|
changed = add_changed(qpdb, newheader, version DNS__DB_FLARG_PASS);
|
||||||
for (top = node->data; top != NULL; top = top->next) {
|
for (top = node->data; top != NULL; top = top->next) {
|
||||||
if (top->typepair == newheader->typepair) {
|
if (top->typepair == newheader->typepair) {
|
||||||
break;
|
break;
|
||||||
@ -5496,7 +5437,6 @@ static dns_dbnode_methods_t qpznode_methods = (dns_dbnode_methods_t){
|
|||||||
static void
|
static void
|
||||||
destroy_qpznode(qpznode_t *node) {
|
destroy_qpznode(qpznode_t *node) {
|
||||||
dns_slabtop_t *top = NULL, *top_next = NULL;
|
dns_slabtop_t *top = NULL, *top_next = NULL;
|
||||||
dns_db_t *db = (dns_db_t *)node->qpdb;
|
|
||||||
|
|
||||||
for (top = node->data; top != NULL; top = top_next) {
|
for (top = node->data; top != NULL; top = top_next) {
|
||||||
top_next = top->next;
|
top_next = top->next;
|
||||||
@ -5508,7 +5448,7 @@ destroy_qpznode(qpznode_t *node) {
|
|||||||
}
|
}
|
||||||
top->header = NULL;
|
top->header = NULL;
|
||||||
|
|
||||||
dns_slabtop_destroy(db->mctx, &top);
|
dns_slabtop_destroy(node->mctx, &top);
|
||||||
}
|
}
|
||||||
|
|
||||||
qpz_heap_unref(node->heap);
|
qpz_heap_unref(node->heap);
|
||||||
@ -5522,12 +5462,6 @@ ISC_REFCOUNT_STATIC_TRACE_IMPL(qpznode, destroy_qpznode);
|
|||||||
ISC_REFCOUNT_STATIC_IMPL(qpznode, destroy_qpznode);
|
ISC_REFCOUNT_STATIC_IMPL(qpznode, destroy_qpznode);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DNS_DB_NODETRACE
|
|
||||||
ISC_REFCOUNT_STATIC_TRACE_IMPL(qpzonedb, qpzone_destroy);
|
|
||||||
#else
|
|
||||||
ISC_REFCOUNT_STATIC_IMPL(qpzonedb, qpzone_destroy);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ISC_REFCOUNT_STATIC_IMPL(qpz_heap, qpz_heap_destroy);
|
ISC_REFCOUNT_STATIC_IMPL(qpz_heap, qpz_heap_destroy);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
x
Reference in New Issue
Block a user