]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Make sure tail_offset is updated after calling expunge handlers
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 5 Feb 2019 22:17:52 +0000 (14:17 -0800)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 7 Jun 2019 10:06:06 +0000 (10:06 +0000)
Since it's a bit troublesome to track whether expunge handlers were actually
called, we can just assume that as long as syncing sees expunges, they were
called (and thet most likely were).

This fixes a bug where dovecot.index.cache header's record_count kept
shrinking and deleted_record_count kept increasing after each sync.
These values were only used to determine when to compress the cache, so
its only effect was that the cache could have been compressed earlier
than necessary.

src/lib-index/mail-index-sync.c

index f168390bc35a61090fa367999ba53a3e087f6a8a..bdc0f399043928a6d0df9301a1a6d82b320569e4 100644 (file)
@@ -25,6 +25,7 @@ struct mail_index_sync_ctx {
        uint32_t next_uid;
 
        bool no_warning:1;
+       bool seen_external_expunges:1;
        bool seen_nonexternal_transactions:1;
        bool fully_synced:1;
 };
@@ -187,8 +188,12 @@ mail_index_sync_read_and_sort(struct mail_index_sync_ctx *ctx)
        while ((ret = mail_transaction_log_view_next(ctx->view->log_view,
                                                     &ctx->hdr,
                                                     &ctx->data)) > 0) {
-               if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0)
+               if ((ctx->hdr->type & MAIL_TRANSACTION_EXTERNAL) != 0) {
+                       if ((ctx->hdr->type & (MAIL_TRANSACTION_EXPUNGE |
+                                              MAIL_TRANSACTION_EXPUNGE_GUID)) != 0)
+                               ctx->seen_external_expunges = TRUE;
                        continue;
+               }
 
                T_BEGIN {
                        if (mail_index_sync_add_transaction(ctx)) {
@@ -797,9 +802,12 @@ mail_index_sync_update_mailbox_offset(struct mail_index_sync_ctx *ctx)
           avoid writing a new tail offset if all the transactions were
           external, because that wouldn't change effective the tail offset.
           except e.g. mdbox map requires this to happen, so do it
-          optionally. */
+          optionally. Also update the tail if we've been calling any expunge
+          handlers, so they won't be called multiple times. That could cause
+          at least cache file's [deleted_]record_count to shrink too much. */
        if ((hdr->log_file_seq != seq || hdr->log_file_tail_offset < offset) &&
-           (ctx->seen_nonexternal_transactions ||
+           (ctx->seen_external_expunges ||
+            ctx->seen_nonexternal_transactions ||
             (ctx->flags & MAIL_INDEX_SYNC_FLAG_UPDATE_TAIL_OFFSET) != 0)) {
                ctx->ext_trans->log_updates = TRUE;
                ctx->ext_trans->tail_offset_changed = TRUE;