]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Fix setting initial last_used for fields in mail_[always_]cache_fields
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 11 May 2020 14:23:19 +0000 (17:23 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 12 May 2020 17:08:40 +0000 (17:08 +0000)
These fields had last_used=0 until the field was accessed. If cache was
purged before this access, the field was dropped. Fixed by assuming
(last_used=0, decision!=NO) is still the first time the field is being
used. This also causes it to trigger mail_cache_decision_changed event.

src/lib-index/mail-cache-decisions.c
src/lib-index/test-mail-cache.c

index 4a8db83997f20d82d7e603cc1a1301ba04160a15..6336fc9f8a5a0ca3e8e7c3639615fc1f558cc557 100644 (file)
@@ -195,14 +195,16 @@ void mail_cache_decision_add(struct mail_cache_view *view, uint32_t seq,
                return;
 
        priv = &cache->fields[field];
-       if (priv->field.decision != MAIL_CACHE_DECISION_NO) {
+       if (priv->field.decision != MAIL_CACHE_DECISION_NO &&
+           priv->field.last_used != 0) {
                /* a) forced decision
                   b) we're already caching it, so it just wasn't in cache */
                return;
        }
 
        /* field used the first time */
-       priv->field.decision = MAIL_CACHE_DECISION_TEMP;
+       if (priv->field.decision == MAIL_CACHE_DECISION_NO)
+               priv->field.decision = MAIL_CACHE_DECISION_TEMP;
        priv->field.last_used = ioloop_time;
        priv->decision_dirty = TRUE;
        cache->field_header_write_pending = TRUE;
@@ -210,12 +212,14 @@ void mail_cache_decision_add(struct mail_cache_view *view, uint32_t seq,
        mail_index_lookup_uid(view->view, seq, &uid);
        priv->uid_highwater = uid;
 
+       const char *new_decision =
+               mail_cache_decision_to_string(priv->field.decision);
        struct event_passthrough *e =
                mail_cache_decision_changed_event(cache, cache->event, field)->
                add_str("reason", "add")->
                add_int("uid", uid)->
                add_str("old_decision", "no")->
-               add_str("new_decision", "temp");
+               add_str("new_decision", new_decision);
        e_debug(e->event(), "Adding field %s to cache for the first time (uid=%u)",
                priv->field.name, uid);
 }
index 315b816ed9be2442a19ffe12378e579b71725158..e4e5503f62f020f1aa18a685ce6036e8f3bbd7c9 100644 (file)
@@ -442,9 +442,8 @@ static void test_mail_cache_add_decisions(void)
                        &ctx.cache->fields[cache_fields[i].idx];
                test_assert_idx(priv->field.decision == expected_decisions[i], i);
                test_assert_idx(!priv->decision_dirty, i);
-               /* uid_highwater is updated only for the changed state */
                uint32_t uid_highwater = priv->uid_highwater;
-               if (i == TEST_FIELD_NO)
+               if (i != TEST_FIELD_NO_FORCED)
                        test_assert_idx(uid_highwater == 1, i);
                else
                        test_assert_idx(uid_highwater == 0, i);