Compare commits

...

3 Commits

Author SHA1 Message Date
Ondřej Surý
e756358ef4 Expire namehooks when purging stale ADB names
Instead of trying to expire entries from adbentrybuckets, expire the
namehooks while purging the stale ADB names.
2022-10-11 09:15:21 +02:00
Ondřej Surý
82c0d2033a Purge stale ADB names globaly, not per bucket
Before the refactoring, there was only few buckets with many names in
them, so cleaning up stale ADB names per-bucket made sense.  After the
refactoring, each bucket directly maps to ADB name, so purging has been
effectively disabled.

Create a global LRU list for ADB names (and ADB entries) and purge the
stale ADB names globally.
2022-10-11 09:15:21 +02:00
Ondřej Surý
dd6f70a334 dns_adb: Remove deadnames and deadentries
Previously, the name and entry buckets were much larger, so the dead
names and entries were moved to a secondary list to be cleaned
later (f.e. after the already running fetch has been canceled).  After
the last refactoring, the bucket now contains only the name (entry)
itself and thus the extra list has a little use.  Remove the .deadnames
and .deadentries from dns_adbnamebucket_t and dns_adbentrybucket_t
structures.
2022-10-11 09:15:21 +02:00

View File

@@ -95,6 +95,8 @@ typedef struct dns_adblameinfo dns_adblameinfo_t;
typedef ISC_LIST(dns_adbentry_t) dns_adbentrylist_t;
typedef struct dns_adbfetch dns_adbfetch_t;
typedef struct dns_adbfetch6 dns_adbfetch6_t;
typedef ISC_LIST(dns_adbnamebucket_t) dns_adbnamebucketlist_t;
typedef ISC_LIST(dns_adbentrybucket_t) dns_adbentrybucketlist_t;
/*% dns adb structure */
struct dns_adb {
@@ -110,9 +112,11 @@ struct dns_adb {
isc_refcount_t references;
dns_adbnamebucketlist_t namebuckets_lru;
isc_ht_t *namebuckets;
isc_rwlock_t names_lock;
dns_adbentrybucketlist_t entrybuckets_lru;
isc_ht_t *entrybuckets;
isc_rwlock_t entries_lock;
@@ -167,9 +171,9 @@ struct dns_adbname {
*/
struct dns_adbnamebucket {
dns_adbnamelist_t names;
dns_adbnamelist_t deadnames;
isc_mutex_t lock;
isc_refcount_t references;
ISC_LINK(dns_adbnamebucket_t) link;
};
/*%
@@ -272,9 +276,9 @@ struct dns_adbentry {
*/
struct dns_adbentrybucket {
dns_adbentrylist_t entries;
dns_adbentrylist_t deadentries;
isc_mutex_t lock;
isc_refcount_t references;
ISC_LINK(dns_adbentrybucket_t) link;
};
/*
@@ -311,7 +315,10 @@ new_adbfetch(dns_adb_t *);
static void
free_adbfetch(dns_adb_t *, dns_adbfetch_t **);
static void
get_namebucket(dns_adb_t *, const dns_name_t *, dns_adbnamebucket_t **);
purge_stale_names(dns_adb_t *adb, isc_stdtime_t now);
static void
get_namebucket(dns_adb_t *, const dns_name_t *, isc_stdtime_t now,
dns_adbnamebucket_t **);
static dns_adbname_t *
get_name(dns_adbnamebucket_t *, const dns_name_t *, unsigned int);
static void
@@ -384,12 +391,6 @@ log_quota(dns_adbentry_t *entry, const char *fmt, ...) ISC_FORMAT_PRINTF(2, 3);
#define NAME_GLUEOK(n) (((n)->flags & NAME_GLUE_OK) != 0)
#define NAME_HINTOK(n) (((n)->flags & NAME_HINT_OK) != 0)
/*
* Private flag(s) for entries.
* MUST NOT overlap FCTX_ADDRINFO_xxx and DNS_FETCHOPT_NOEDNS0.
*/
#define ENTRY_IS_DEAD 0x00400000
/*
* To the name, address classes are all that really exist. If it has a
* V6 address it doesn't care if it came from a AAAA query.
@@ -580,13 +581,7 @@ _entry_detach(dns_adbentry_t **entryp, const char *func, const char *file,
#endif /* ADB_TRACE */
if (refs == 1) {
/*
* If the entry is linked to a bucket, we need to
* unlink it before destroying it.
*/
if (ISC_LINK_LINKED(entry, plink)) {
unlink_entry(entry);
}
unlink_entry(entry);
free_adbentry(&entry);
}
}
@@ -782,9 +777,6 @@ expire_name(dns_adbname_t **n, isc_eventtype_t evtype) {
* we'll clean it up later.
*/
if (!NAME_DEAD(adbname)) {
dns_adbnamebucket_t *nbucket = adbname->bucket;
ISC_LIST_UNLINK(nbucket->names, adbname, plink);
ISC_LIST_APPEND(nbucket->deadnames, adbname, plink);
adbname->flags |= NAME_IS_DEAD;
}
}
@@ -866,11 +858,7 @@ unlink_name(dns_adbname_t *name) {
REQUIRE(nbucket != NULL);
if (NAME_DEAD(name)) {
ISC_LIST_UNLINK(nbucket->deadnames, name, plink);
} else {
ISC_LIST_UNLINK(nbucket->names, name, plink);
}
ISC_LIST_UNLINK(nbucket->names, name, plink);
isc_refcount_decrement(&nbucket->references);
}
@@ -885,40 +873,6 @@ link_entry(dns_adbentrybucket_t *ebucket, dns_adbentry_t *entry) {
DP(DEF_LEVEL, "link ADB entry %p to bucket %p", entry, ebucket);
/*
* If we're in the overmem condition, take this opportunity to
* clean up the least-recently used entries in the bucket.
*/
if (isc_mem_isovermem(entry->adb->mctx)) {
int i;
DP(ISC_LOG_DEBUG(1), "adb: overmem, cleaning bucket %p",
ebucket);
for (i = 0; i < 2; i++) {
dns_adbentry_t *e = ISC_LIST_TAIL(ebucket->entries);
if (e == NULL) {
break;
}
/*
* If the only reference to an entry is from
* the bucket itself, we can kill it. Otherwise
* we move it to deadentries and kill it later.
*/
if (isc_refcount_current(&e->references) == 1) {
unlink_entry(e);
entry_detach(&e);
continue;
}
INSIST((e->flags & ENTRY_IS_DEAD) == 0);
e->flags |= ENTRY_IS_DEAD;
ISC_LIST_UNLINK(ebucket->entries, e, plink);
ISC_LIST_PREPEND(ebucket->deadentries, e, plink);
}
}
entry->bucket = ebucket;
ISC_LIST_PREPEND(ebucket->entries, entry, plink);
isc_refcount_increment0(&ebucket->references);
@@ -941,31 +895,20 @@ unlink_entry(dns_adbentry_t *entry) {
DP(DEF_LEVEL, "unlink ADB entry %p from bucket %p", entry, ebucket);
if ((entry->flags & ENTRY_IS_DEAD) != 0) {
ISC_LIST_UNLINK(ebucket->deadentries, entry, plink);
} else {
ISC_LIST_UNLINK(ebucket->entries, entry, plink);
}
ISC_LIST_UNLINK(ebucket->entries, entry, plink);
isc_refcount_decrement(&ebucket->references);
}
static void
shutdown_names(dns_adb_t *adb) {
isc_result_t result;
isc_ht_iter_t *it = NULL;
dns_adbnamebucket_t *nbucket = NULL;
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->namebuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
for (nbucket = ISC_LIST_HEAD(adb->namebuckets_lru); nbucket != NULL;
nbucket = ISC_LIST_NEXT(nbucket, link))
{
dns_adbnamebucket_t *nbucket = NULL;
dns_adbname_t *name = NULL;
dns_adbname_t *next_name = NULL;
isc_ht_iter_current(it, (void **)&nbucket);
INSIST(nbucket != NULL);
LOCK(&nbucket->lock);
/*
@@ -976,56 +919,36 @@ shutdown_names(dns_adb_t *adb) {
*/
name = ISC_LIST_HEAD(nbucket->names);
while (name != NULL) {
next_name = ISC_LIST_NEXT(name, plink);
dns_adbname_t *next_name = ISC_LIST_NEXT(name, plink);
expire_name(&name, DNS_EVENT_ADBSHUTDOWN);
name = next_name;
}
UNLOCK(&nbucket->lock);
}
isc_ht_iter_destroy(&it);
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
}
static void
shutdown_entries(dns_adb_t *adb) {
isc_result_t result;
isc_ht_iter_t *iter = NULL;
dns_adbentrybucket_t *ebucket = NULL;
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->entrybuckets, &iter);
for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(iter))
for (ebucket = ISC_LIST_HEAD(adb->entrybuckets_lru); ebucket != NULL;
ebucket = ISC_LIST_NEXT(ebucket, link))
{
dns_adbentrybucket_t *ebucket = NULL;
dns_adbentry_t *entry = NULL;
dns_adbentry_t *next_entry = NULL;
isc_ht_iter_current(iter, (void **)&ebucket);
INSIST(ebucket != NULL);
LOCK(&ebucket->lock);
entry = ISC_LIST_HEAD(ebucket->entries);
while (entry != NULL) {
/*
* Run through the list and clean up any
* entries not in use.
*/
for (entry = ISC_LIST_HEAD(ebucket->entries); entry != NULL;
entry = next_entry) {
next_entry = ISC_LIST_NEXT(entry, plink);
if (isc_refcount_current(&entry->references) == 1 &&
entry->expires == 0) {
unlink_entry(entry);
}
entry_detach(&entry);
entry = next_entry;
}
UNLOCK(&ebucket->lock);
}
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
isc_ht_iter_destroy(&iter);
}
/*
@@ -1033,7 +956,6 @@ shutdown_entries(dns_adb_t *adb) {
*/
static void
clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
dns_adbentrybucket_t *ebucket = NULL;
dns_adbnamehook_t *namehook = NULL;
namehook = ISC_LIST_HEAD(*namehooks);
@@ -1044,27 +966,17 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
* Clean up the entry if needed.
*/
if (namehook->entry != NULL) {
dns_adbentrybucket_t *ebucket = NULL;
INSIST(DNS_ADBENTRY_VALID(namehook->entry));
/*
* If entry bucket for the next address is
* different from the previous one, then
* unlock the old one, lock the new one, and
* carry on. (This way we don't necessarily
* have to lock and unlock for every list
* member.)
*/
if (ebucket != namehook->entry->bucket) {
if (ebucket != NULL) {
UNLOCK(&ebucket->lock);
}
ebucket = namehook->entry->bucket;
INSIST(ebucket != NULL);
LOCK(&ebucket->lock);
}
ebucket = namehook->entry->bucket;
INSIST(ebucket != NULL);
LOCK(&ebucket->lock);
namehook->entry->nh--;
entry_detach(&namehook->entry);
UNLOCK(&ebucket->lock);
}
/*
@@ -1075,10 +987,6 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
namehook = ISC_LIST_HEAD(*namehooks);
}
if (ebucket != NULL) {
UNLOCK(&ebucket->lock);
}
}
static void
@@ -1325,7 +1233,7 @@ new_adbnamebucket(dns_adb_t *adb) {
};
ISC_LIST_INIT(nbucket->names);
ISC_LIST_INIT(nbucket->deadnames);
ISC_LINK_INIT(nbucket, link);
isc_mutex_init(&nbucket->lock);
isc_refcount_init(&nbucket->references, 0);
@@ -1466,7 +1374,7 @@ new_adbentrybucket(dns_adb_t *adb) {
};
ISC_LIST_INIT(ebucket->entries);
ISC_LIST_INIT(ebucket->deadentries);
ISC_LINK_INIT(ebucket, link);
isc_mutex_init(&ebucket->lock);
isc_refcount_init(&ebucket->references, 0);
@@ -1598,7 +1506,7 @@ free_adbaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **ainfo) {
* Search for the name bucket in the hash table.
*/
static void
get_namebucket(dns_adb_t *adb, const dns_name_t *name,
get_namebucket(dns_adb_t *adb, const dns_name_t *name, isc_stdtime_t now,
dns_adbnamebucket_t **nbucketp) {
isc_result_t result;
dns_adbnamebucket_t *nbucket = NULL;
@@ -1606,6 +1514,11 @@ get_namebucket(dns_adb_t *adb, const dns_name_t *name,
REQUIRE(nbucketp != NULL && *nbucketp == NULL);
RWLOCK(&adb->names_lock, isc_rwlocktype_write);
/*
* First, see if there are stale names at the
* end of the list, and purge them if so.
*/
purge_stale_names(adb, now);
result = isc_ht_find(adb->namebuckets, name->ndata, name->length,
(void **)&nbucket);
if (result == ISC_R_NOTFOUND) {
@@ -1615,7 +1528,10 @@ get_namebucket(dns_adb_t *adb, const dns_name_t *name,
nbucket = new_adbnamebucket(adb);
result = isc_ht_add(adb->namebuckets, name->ndata, name->length,
nbucket);
} else {
ISC_LIST_UNLINK(adb->namebuckets_lru, nbucket, link);
}
ISC_LIST_PREPEND(adb->namebuckets_lru, nbucket, link);
RWUNLOCK(&adb->names_lock, isc_rwlocktype_write);
INSIST(result == ISC_R_SUCCESS);
@@ -1666,7 +1582,10 @@ get_entrybucket(dns_adb_t *adb, const isc_sockaddr_t *addr,
result = isc_ht_add(adb->entrybuckets,
(const unsigned char *)addr, sizeof(*addr),
ebucket);
} else {
ISC_LIST_UNLINK(adb->entrybuckets_lru, ebucket, link);
}
ISC_LIST_PREPEND(adb->entrybuckets_lru, ebucket, link);
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_write);
INSIST(result == ISC_R_SUCCESS);
@@ -1884,55 +1803,58 @@ maybe_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
* is in the overmem condition, the tail and the next to tail entries
* will be unconditionally removed (unless they have an outstanding fetch).
* We don't care about a race on 'overmem' at the risk of causing some
* collateral damage or a small delay in starting cleanup, so we don't bother
* to lock ADB (if it's not locked).
* collateral damage or a small delay in starting cleanup.
*
* Name bucket must be locked; adb may be locked; no other locks held.
* adb->names_lock MUST be write locked
*/
static void
purge_stale_names(dns_adb_t *adb, dns_adbnamebucket_t *nbucket,
isc_stdtime_t now) {
dns_adbname_t *adbname = NULL, *next_adbname = NULL;
purge_stale_names(dns_adb_t *adb, isc_stdtime_t now) {
dns_adbnamebucket_t *nbucket = NULL;
bool overmem = isc_mem_isovermem(adb->mctx);
int max_removed = overmem ? 2 : 1;
int scans = 0, removed = 0;
REQUIRE(nbucket != NULL);
/*
* We limit the number of scanned entries to 10 (arbitrary choice)
* in order to avoid examining too many entries when there are many
* tail entries that have fetches (this should be rare, but could
* happen).
*/
for (adbname = ISC_LIST_TAIL(nbucket->names);
adbname != NULL && removed < max_removed && scans < 10;
adbname = next_adbname)
{
INSIST(!NAME_DEAD(adbname));
next_adbname = ISC_LIST_PREV(adbname, plink);
for (nbucket = ISC_LIST_TAIL(adb->namebuckets_lru);
nbucket != NULL && removed < max_removed && scans < 10;
nbucket = ISC_LIST_PREV(nbucket, link))
{
dns_adbname_t *adbname = NULL;
dns_adbname_t *next_adbname = NULL;
LOCK(&nbucket->lock);
scans++;
/*
* Remove the name if it's expired or unused, has no
* address data, and there are no active fetches.
*/
maybe_expire_name(&adbname, now);
if (adbname == NULL) {
removed++;
if (overmem) {
for (adbname = ISC_LIST_HEAD(nbucket->names); adbname != NULL;
adbname = next_adbname)
{
next_adbname = ISC_LIST_PREV(adbname, plink);
/*
* Remove the name if it's expired or unused,
* has no address data.
*/
maybe_expire_namehooks(adbname, now);
maybe_expire_name(&adbname, now);
if (adbname == NULL) {
removed++;
continue;
}
break;
}
if (!NAME_FETCH(adbname) &&
(overmem || adbname->last_used + ADB_STALE_MARGIN <= now))
{
expire_name(&adbname, DNS_EVENT_ADBCANCELED);
removed++;
if (overmem ||
adbname->last_used + ADB_STALE_MARGIN <= now) {
expire_name(&adbname, DNS_EVENT_ADBCANCELED);
removed++;
}
}
UNLOCK(&nbucket->lock);
}
}
@@ -1961,7 +1883,6 @@ maybe_expire_entry(dns_adbentry_t **entryp, isc_stdtime_t now) {
*entryp = NULL;
DP(DEF_LEVEL, "killing entry %p", entry);
INSIST(ISC_LINK_LINKED(entry, plink));
unlink_entry(entry);
entry_detach(&entry);
}
@@ -2014,31 +1935,23 @@ cleanup_entries(dns_adbentrybucket_t *ebucket, isc_stdtime_t now) {
static void
clean_hashes(dns_adb_t *adb, isc_stdtime_t now) {
isc_result_t result;
isc_ht_iter_t *it = NULL;
dns_adbnamebucket_t *nbucket = NULL;
dns_adbentrybucket_t *ebucket = NULL;
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->namebuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
for (nbucket = ISC_LIST_HEAD(adb->namebuckets_lru); nbucket != NULL;
nbucket = ISC_LIST_NEXT(nbucket, link))
{
dns_adbnamebucket_t *nbucket = NULL;
isc_ht_iter_current(it, (void **)&nbucket);
cleanup_names(nbucket, now);
}
isc_ht_iter_destroy(&it);
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->entrybuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
for (ebucket = ISC_LIST_HEAD(adb->entrybuckets_lru); ebucket != NULL;
ebucket = ISC_LIST_NEXT(ebucket, link))
{
dns_adbentrybucket_t *ebucket = NULL;
isc_ht_iter_current(it, (void **)&ebucket);
cleanup_entries(ebucket, now);
}
isc_ht_iter_destroy(&it);
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
}
@@ -2061,6 +1974,7 @@ destroy(dns_adb_t *adb) {
cleanup_names(nbucket, INT_MAX);
isc_mutex_destroy(&nbucket->lock);
isc_refcount_destroy(&nbucket->references);
ISC_LIST_UNLINK(adb->namebuckets_lru, nbucket, link);
isc_mem_put(adb->mctx, nbucket, sizeof(*nbucket));
}
isc_ht_iter_destroy(&it);
@@ -2078,6 +1992,7 @@ destroy(dns_adb_t *adb) {
cleanup_entries(ebucket, INT_MAX);
isc_mutex_destroy(&ebucket->lock);
isc_refcount_destroy(&ebucket->references);
ISC_LIST_UNLINK(adb->entrybuckets_lru, ebucket, link);
isc_mem_put(adb->mctx, ebucket, sizeof(*ebucket));
}
isc_ht_iter_destroy(&it);
@@ -2124,9 +2039,11 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_taskmgr_t *taskmgr,
dns_resolver_attach(view->resolver, &adb->res);
isc_mem_attach(mem, &adb->mctx);
ISC_LIST_INIT(adb->namebuckets_lru);
isc_ht_init(&adb->namebuckets, adb->mctx, 1, ISC_HT_CASE_INSENSITIVE);
isc_rwlock_init(&adb->names_lock, 0, 0);
ISC_LIST_INIT(adb->entrybuckets_lru);
isc_ht_init(&adb->entrybuckets, adb->mctx, 1, ISC_HT_CASE_SENSITIVE);
isc_rwlock_init(&adb->entries_lock, 0, 0);
@@ -2166,9 +2083,11 @@ free_lock:
isc_rwlock_destroy(&adb->entries_lock);
isc_ht_destroy(&adb->entrybuckets);
INSIST(ISC_LIST_EMPTY(adb->entrybuckets_lru));
isc_rwlock_destroy(&adb->names_lock);
isc_ht_destroy(&adb->namebuckets);
INSIST(ISC_LIST_EMPTY(adb->namebuckets_lru));
dns_resolver_detach(&adb->res);
dns_view_weakdetach(&adb->view);
@@ -2316,17 +2235,15 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action,
/*
* Try to see if we know anything about this name at all.
*/
get_namebucket(adb, name, &nbucket);
get_namebucket(adb, name, now, &nbucket);
INSIST(nbucket != NULL);
LOCK(&nbucket->lock);
adbname = get_name(nbucket, name, find->options);
if (adbname == NULL) {
/*
* Nothing found. Allocate a new adbname structure for
* this name. First, see if there are stale names at the
* end of the list, and purge them if so.
* this name.
*/
purge_stale_names(adb, nbucket, now);
adbname = new_adbname(adb, name);
link_name(nbucket, adbname);
@@ -2726,8 +2643,8 @@ dump_ttl(FILE *f, const char *legend, isc_stdtime_t value, isc_stdtime_t now) {
*/
static void
dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
isc_result_t result;
isc_ht_iter_t *it = NULL;
dns_adbnamebucket_t *nbucket = NULL;
dns_adbentrybucket_t *ebucket = NULL;
fprintf(f, ";\n; Address database dump\n;\n");
fprintf(f, "; [edns success/timeout]\n");
@@ -2741,15 +2658,11 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
* Ensure this operation is applied to both hash tables at once.
*/
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->namebuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
for (nbucket = ISC_LIST_HEAD(adb->namebuckets_lru); nbucket != NULL;
nbucket = ISC_LIST_NEXT(nbucket, link))
{
dns_adbnamebucket_t *nbucket = NULL;
dns_adbname_t *name = NULL;
isc_ht_iter_current(it, (void **)&nbucket);
LOCK(&nbucket->lock);
if (debug) {
static int n = 0;
@@ -2796,20 +2709,16 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
}
UNLOCK(&nbucket->lock);
}
isc_ht_iter_destroy(&it);
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
fprintf(f, ";\n; Unassociated entries\n;\n");
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->entrybuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
for (ebucket = ISC_LIST_HEAD(adb->entrybuckets_lru); ebucket != NULL;
ebucket = ISC_LIST_NEXT(ebucket, link))
{
dns_adbentrybucket_t *ebucket = NULL;
dns_adbentry_t *entry = NULL;
isc_ht_iter_current(it, (void **)&ebucket);
LOCK(&ebucket->lock);
for (entry = ISC_LIST_HEAD(ebucket->entries); entry != NULL;
@@ -2821,8 +2730,6 @@ dump_adb(dns_adb_t *adb, FILE *f, bool debug, isc_stdtime_t now) {
}
UNLOCK(&ebucket->lock);
}
isc_ht_iter_destroy(&it);
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
}
@@ -2993,20 +2900,16 @@ putstr(isc_buffer_t **b, const char *str) {
isc_result_t
dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf) {
isc_result_t result;
isc_ht_iter_t *it = NULL;
dns_adbentrybucket_t *ebucket = NULL;
REQUIRE(DNS_ADB_VALID(adb));
RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->entrybuckets, &it);
for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(it))
for (ebucket = ISC_LIST_HEAD(adb->entrybuckets_lru); ebucket != NULL;
ebucket = ISC_LIST_NEXT(ebucket, link))
{
dns_adbentrybucket_t *ebucket = NULL;
dns_adbentry_t *entry = NULL;
isc_ht_iter_current(it, (void **)&ebucket);
LOCK(&ebucket->lock);
for (entry = ISC_LIST_HEAD(ebucket->entries); entry != NULL;
entry = ISC_LIST_NEXT(entry, plink))
@@ -3031,12 +2934,8 @@ dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf) {
UNLOCK(&ebucket->lock);
}
RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
isc_ht_iter_destroy(&it);
if (result == ISC_R_NOMORE) {
result = ISC_R_SUCCESS;
}
return (result);
return (ISC_R_SUCCESS);
}
static isc_result_t
@@ -3556,9 +3455,6 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr, unsigned int bits,
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
REQUIRE((bits & ENTRY_IS_DEAD) == 0);
REQUIRE((mask & ENTRY_IS_DEAD) == 0);
ebucket = addr->entry->bucket;
LOCK(&ebucket->lock);
@@ -3942,8 +3838,7 @@ dns_adb_flushname(dns_adb_t *adb, const dns_name_t *name) {
void
dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
isc_result_t result;
isc_ht_iter_t *iter = NULL;
dns_adbnamebucket_t *nbucket = NULL;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(name != NULL);
@@ -3953,14 +3848,11 @@ dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
}
RWLOCK(&adb->names_lock, isc_rwlocktype_read);
isc_ht_iter_create(adb->namebuckets, &iter);
for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS;
result = isc_ht_iter_next(iter))
for (nbucket = ISC_LIST_HEAD(adb->namebuckets_lru); nbucket != NULL;
nbucket = ISC_LIST_NEXT(nbucket, link))
{
dns_adbnamebucket_t *nbucket = NULL;
dns_adbname_t *adbname = NULL, *nextname = NULL;
isc_ht_iter_current(iter, (void **)&nbucket);
LOCK(&nbucket->lock);
adbname = ISC_LIST_HEAD(nbucket->names);
while (adbname != NULL) {
@@ -3973,7 +3865,6 @@ dns_adb_flushnames(dns_adb_t *adb, const dns_name_t *name) {
}
UNLOCK(&nbucket->lock);
}
isc_ht_iter_destroy(&iter);
RWUNLOCK(&adb->names_lock, isc_rwlocktype_read);
}