* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.270.12.34 2011/10/13 00:37:34 marka Exp $ */
+/* $Id: rbtdb.c,v 1.270.12.35 2011/11/08 21:20:57 marka Exp $ */
/*! \file */
unsigned int lockrefs, noderefs;
isc_refcount_t *lockref;
+ INSIST(!ISC_LINK_LINKED(node, deadlink));
dns_rbtnode_refincrement0(node, &noderefs);
if (noderefs == 1) { /* this is the first reference to the node */
lockref = &rbtdb->node_locks[node->locknum].references;
isc_boolean_t need_relock = ISC_FALSE;
NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
- new_reference(rbtdb, node);
-
NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock,
isc_rwlocktype_read);
if (ISC_LINK_LINKED(node, deadlink))
NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock,
isc_rwlocktype_write);
}
-
+ new_reference(rbtdb, node);
NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
}
ISC_LOG_INFO,
"decrement_reference: failed to "
"allocate pruning event");
+ INSIST(node->data == NULL);
INSIST(!ISC_LINK_LINKED(node, deadlink));
ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node,
deadlink);
}
}
} else if (dns_rbtnode_refcurrent(node) == 0) {
+ INSIST(node->data == NULL);
INSIST(!ISC_LINK_LINKED(node, deadlink));
ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink);
} else
* from the list beforehand as we do in
* reactivate_node().
*/
- new_reference(rbtdb, parent);
- if (ISC_LINK_LINKED(parent, deadlink)) {
+ if (ISC_LINK_LINKED(parent, deadlink))
ISC_LIST_UNLINK(rbtdb->deadnodes[locknum],
parent, deadlink);
- }
+ new_reference(rbtdb, parent);
} else
parent = NULL;
}
static isc_result_t
-findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
- dns_dbnode_t **nodep)
+findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, dns_name_t *name,
+ isc_boolean_t create, dns_dbnode_t **nodep)
{
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
dns_rbtnode_t *node = NULL;
dns_name_t nodename;
isc_result_t result;
isc_rwlocktype_t locktype = isc_rwlocktype_read;
- REQUIRE(VALID_RBTDB(rbtdb));
+ INSIST(tree == rbtdb->tree || tree == rbtdb->nsec3);
dns_name_init(&nodename, NULL);
RWLOCK(&rbtdb->tree_lock, locktype);
- result = dns_rbt_findnode(rbtdb->tree, name, NULL, &node, NULL,
+ result = dns_rbt_findnode(tree, name, NULL, &node, NULL,
DNS_RBTFIND_EMPTYDATA, NULL, NULL);
if (result != ISC_R_SUCCESS) {
RWUNLOCK(&rbtdb->tree_lock, locktype);
locktype = isc_rwlocktype_write;
RWLOCK(&rbtdb->tree_lock, locktype);
node = NULL;
- result = dns_rbt_addnode(rbtdb->tree, name, &node);
+ result = dns_rbt_addnode(tree, name, &node);
if (result == ISC_R_SUCCESS) {
dns_rbt_namefromnode(node, &nodename);
#ifdef DNS_RBT_USEHASH
node->locknum = dns_name_hash(&nodename, ISC_TRUE) %
rbtdb->node_lock_count;
#endif
- node->nsec3 = 0;
- add_empty_wildcards(rbtdb, name);
-
- if (dns_name_iswildcard(name)) {
- result = add_wildcard_magic(rbtdb, name);
- if (result != ISC_R_SUCCESS) {
- RWUNLOCK(&rbtdb->tree_lock, locktype);
- return (result);
+ if (tree == rbtdb->tree) {
+ node->nsec3 = 0;
+ add_empty_wildcards(rbtdb, name);
+
+ if (dns_name_iswildcard(name)) {
+ result = add_wildcard_magic(rbtdb,
+ name);
+ if (result != ISC_R_SUCCESS) {
+ RWUNLOCK(&rbtdb->tree_lock,
+ locktype);
+ return (result);
+ }
}
}
+ if (tree == rbtdb->nsec3)
+ node->nsec = 1;
} else if (result != ISC_R_EXISTS) {
RWUNLOCK(&rbtdb->tree_lock, locktype);
return (result);
}
}
+
+ if (tree == rbtdb->nsec3)
+ INSIST(node->nsec == 1);
+
reactivate_node(rbtdb, node, locktype);
RWUNLOCK(&rbtdb->tree_lock, locktype);
}
static isc_result_t
-findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
dns_dbnode_t **nodep)
{
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- dns_rbtnode_t *node = NULL;
- dns_name_t nodename;
- isc_result_t result;
- isc_rwlocktype_t locktype = isc_rwlocktype_read;
REQUIRE(VALID_RBTDB(rbtdb));
- dns_name_init(&nodename, NULL);
- RWLOCK(&rbtdb->tree_lock, locktype);
- result = dns_rbt_findnode(rbtdb->nsec3, name, NULL, &node, NULL,
- DNS_RBTFIND_EMPTYDATA, NULL, NULL);
- if (result != ISC_R_SUCCESS) {
- RWUNLOCK(&rbtdb->tree_lock, locktype);
- if (!create) {
- if (result == DNS_R_PARTIALMATCH)
- result = ISC_R_NOTFOUND;
- return (result);
- }
- /*
- * It would be nice to try to upgrade the lock instead of
- * unlocking then relocking.
- */
- locktype = isc_rwlocktype_write;
- RWLOCK(&rbtdb->tree_lock, locktype);
- node = NULL;
- result = dns_rbt_addnode(rbtdb->nsec3, name, &node);
- if (result == ISC_R_SUCCESS) {
- dns_rbt_namefromnode(node, &nodename);
-#ifdef DNS_RBT_USEHASH
- node->locknum = node->hashval % rbtdb->node_lock_count;
-#else
- node->locknum = dns_name_hash(&nodename, ISC_TRUE) %
- rbtdb->node_lock_count;
-#endif
- node->nsec3 = 1U;
- } else if (result != ISC_R_EXISTS) {
- RWUNLOCK(&rbtdb->tree_lock, locktype);
- return (result);
- }
- } else
- INSIST(node->nsec3);
- NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
- new_reference(rbtdb, node);
- NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
- RWUNLOCK(&rbtdb->tree_lock, locktype);
+ return (findnodeintree(rbtdb, rbtdb->tree, name, create, nodep));
+}
- *nodep = (dns_dbnode_t *)node;
+static isc_result_t
+findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create,
+ dns_dbnode_t **nodep)
+{
+ dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- return (ISC_R_SUCCESS);
+ REQUIRE(VALID_RBTDB(rbtdb));
+
+ return (findnodeintree(rbtdb, rbtdb->nsec3, name, create, nodep));
}
static isc_result_t