]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/cache/top: fix counting the whole record size instead of just eh
authorLukáš Ondráček <lukas.ondracek@nic.cz>
Thu, 13 Nov 2025 14:31:28 +0000 (15:31 +0100)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 1 Dec 2025 12:27:11 +0000 (13:27 +0100)
lib/cache/api.c
lib/cache/entry_list.c
lib/cache/entry_pkt.c
lib/cache/impl.h
lib/cache/peek.c

index 43f4beb9994f72e7f0496880931550b71c618794..92907eaaf0eb2cfb3dd94356ab624f2e8d50ab6a 100644 (file)
@@ -637,8 +637,9 @@ static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry,
        };
 
        /* Prepare raw memory for the new entry. */
+       size_t whole_val_len = 0;
        ret = entry_h_splice(&val_new_entry, rank, key, k->type, rr->type,
-                               rr->owner, qry, cache, timestamp);
+                               rr->owner, qry, cache, timestamp, &whole_val_len);
        if (ret) return kr_ok(); /* some aren't really errors */
        if (kr_fails_assert(val_new_entry.data))
                return kr_error(EFAULT);
@@ -654,7 +655,7 @@ static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry,
        if (kr_fails_assert(entry_h_consistent_E(val_new_entry, rr->type)))
                return kr_error(EINVAL);
        if (qry) // it's possible to insert outside a request
-               kr_cache_top_access(qry->request, key.data, key.len, val_new_entry.len, "stash_rrset");
+               kr_cache_top_access(qry->request, key.data, key.len, whole_val_len, "stash_rrset");
 
        #if 0 /* Occasionally useful when debugging some kinds of changes. */
        {
index 4dced2fe746eb4eb6e9f9c0e450a52d659406fca..e8d2c53483c4bb907952c90bc6fd626d9b9b8722 100644 (file)
@@ -215,7 +215,8 @@ int entry_h_splice(
        knot_db_val_t *val_new_entry, uint8_t rank,
        const knot_db_val_t key, const uint16_t ktype, const uint16_t type,
        const knot_dname_t *owner/*log only*/,
-       const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp)
+       const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp,
+       size_t *cache_record_size_out)
 {
        //TODO: another review, perhaps including the API
        if (kr_fails_assert(val_new_entry && val_new_entry->len > 0))
@@ -272,6 +273,7 @@ int entry_h_splice(
 
        if (!i_type) {
                /* The non-list types are trivial now. */
+               *cache_record_size_out = val_new_entry->len;
                return cache_write_or_clear(cache, &key, val_new_entry, qry);
        }
        /* Now we're in trouble.  In some cases, parts of data to be written
@@ -291,6 +293,7 @@ int entry_h_splice(
        };
        uint8_t buf[val.len];
        entry_list_memcpy((struct entry_apex *)buf, el);
+       *cache_record_size_out = val.len;
        ret = cache_write_or_clear(cache, &key, &val, qry);
        if (ret) return kr_error(ret);
        memcpy(val.data, buf, val.len); /* we also copy the "empty" space, but well... */
index d76b8b95f9505fefc863ba4d318aa8d99262d3d7..228eabb789afe7c967d3a9a70e07e6c19841746a 100644 (file)
@@ -102,8 +102,9 @@ void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry,
        };
        /* Prepare raw memory for the new entry and fill it. */
        struct kr_cache *cache = &req->ctx->cache;
+       size_t whole_val_len = 0;
        ret = entry_h_splice(&val_new_entry, rank, key, k->type, pkt_type,
-                               owner, qry, cache, qry->timestamp.tv_sec);
+                               owner, qry, cache, qry->timestamp.tv_sec, &whole_val_len);
        if (ret || kr_fails_assert(val_new_entry.data)) return; /* some aren't really errors */
        struct entry_h *eh = val_new_entry.data;
        memset(eh, 0, offsetof(struct entry_h, data));
@@ -114,7 +115,7 @@ void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry,
        eh->has_optout = qf->DNSSEC_OPTOUT;
        memcpy(eh->data, &pkt_size, sizeof(pkt_size));
        memcpy(eh->data + sizeof(pkt_size), pkt->wire, pkt_size);
-       kr_cache_top_access(req, key.data, key.len, val_new_entry.len, "stash_pkt");
+       kr_cache_top_access(req, key.data, key.len, whole_val_len, "stash_pkt");
 
        WITH_VERBOSE(qry) {
                auto_free char *type_str = kr_rrtype_text(pkt_type),
index 0ca3a6562226bd02b642a04f466a280d16a95fcf..c585ef6a4a4be3b9488bf2ea42bd64d4d741ef30 100644 (file)
@@ -226,14 +226,15 @@ int entry_h_seek(knot_db_val_t *val, uint16_t type);
  * Some checks are performed (rank, TTL), the current entry in cache is copied
  * with a hole ready for the new entry (old one of the same type is cut out).
  *
- * \param val_new_entry The only changing parameter; ->len is read, ->data written.
+ * \param val_new_entry ->len is read, ->data written.
  * \return error code
  */
 int entry_h_splice(
        knot_db_val_t *val_new_entry, uint8_t rank,
        const knot_db_val_t key, const uint16_t ktype, const uint16_t type,
        const knot_dname_t *owner/*log only*/,
-       const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp);
+       const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp,
+       size_t *cache_record_size_out);
 
 /** Parse an entry_apex into individual items.  @return error code. */
 KR_EXPORT int entry_list_parse(const knot_db_val_t val, entry_list_t list);
index 121ce8ebc57292338a2ec476f8e51d8afb12abc6..9c8c4ceb4c41ea456019f7b8de12106a58fd41a9 100644 (file)
@@ -123,12 +123,13 @@ int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt)
                knot_db_val_t key = key_exact_type_maypkt(k, qry->stype);
                knot_db_val_t val = { NULL, 0 };
                ret = cache_op(cache, read, &key, &val, 1);
+               size_t whole_val_len = val.len;
                if (!ret) {
                        /* found an entry: test conditions, materialize into pkt, etc. */
                        ret = found_exact_hit(qry, pkt, val, lowest_rank);
                }
                if (!ret) {
-                       kr_cache_top_access(req, key.data, key.len, val.len, "peek_nosync:exact");  // hits only
+                       kr_cache_top_access(req, key.data, key.len, whole_val_len, "peek_nosync:exact");  // hits only
                        return KR_STATE_DONE;
                } else if (kr_fails_assert(ret == kr_error(ENOENT))) {
                        VERBOSE_MSG(qry, "=> exact hit error: %d %s\n", ret, kr_strerror(ret));