]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: mail_cache_decisions_copy() - Create transaction internally
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 27 Mar 2020 09:33:23 +0000 (11:33 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 15 Apr 2020 09:41:42 +0000 (12:41 +0300)
src/lib-index/mail-cache-decisions.c
src/lib-index/mail-cache.h
src/lib-storage/mail-storage.c

index 953172ec9e5a7af711743b3a529c3a4c87ecb742..496922fea093000661170389b7689b7e7d4acb94 100644 (file)
@@ -152,15 +152,19 @@ void mail_cache_decision_add(struct mail_cache_view *view, uint32_t seq,
        cache->fields[field].uid_highwater = uid;
 }
 
-void mail_cache_decisions_copy(struct mail_index_transaction *itrans,
-                              struct mail_cache *src,
-                              struct mail_cache *dst)
+int mail_cache_decisions_copy(struct mail_cache *src, struct mail_cache *dst)
 {
        struct mail_cache_compress_lock *lock = NULL;
 
-       if (mail_cache_open_and_verify(src) < 0 ||
-           MAIL_CACHE_IS_UNUSABLE(src))
-               return;
+       if (mail_cache_open_and_verify(src) < 0)
+               return -1;
+       if (MAIL_CACHE_IS_UNUSABLE(src))
+               return 0; /* no caching decisions */
+
+       struct mail_index_view *dest_view = mail_index_view_open(dst->index);
+       struct mail_index_transaction *itrans =
+               mail_index_transaction_begin(dest_view,
+                                            MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
 
        unsigned int count = 0;
        struct mail_cache_field *fields =
@@ -169,8 +173,16 @@ void mail_cache_decisions_copy(struct mail_index_transaction *itrans,
        if (count > 0)
                mail_cache_register_fields(dst, fields, count);
 
+       /* Destination cache isn't expected to exist yet, so use compression
+          to create it. Setting field_header_write_pending also guarantees
+          that the fields are updated even if the cache was already created
+          and no compression was done. */
        dst->field_header_write_pending = TRUE;
-       (void)mail_cache_compress(dst, itrans, &lock);
+       int ret = mail_cache_compress(dst, itrans, &lock);
        if (lock != NULL)
                mail_cache_compress_unlock(&lock);
+       if (mail_index_transaction_commit(&itrans) < 0)
+               ret = -1;
+       mail_index_view_close(&dest_view);
+       return ret;
 }
index 1f51d989ae4c94d14b75b4efd3b1235db8c43b71..f90735ab6757a5dfae866e1eb41b08b38ed7e790 100644 (file)
@@ -93,10 +93,9 @@ void mail_cache_view_close(struct mail_cache_view **view);
 void mail_cache_view_update_cache_decisions(struct mail_cache_view *view,
                                            bool update);
 
-/* Copy caching decisions */
-void mail_cache_decisions_copy(struct mail_index_transaction *itrans,
-                              struct mail_cache *src,
-                              struct mail_cache *dst);
+/* Copy caching decisions. This is expected to be called only for a newly
+   created empty mailbox. */
+int mail_cache_decisions_copy(struct mail_cache *src, struct mail_cache *dst);
 
 /* Get index transaction specific cache transaction. */
 struct mail_cache_transaction_ctx *
index 980d88abefefb518f76399dfbb5e90747f9d7a67..da49488d9b094e386ac4b38f2c0ce370e7cc1003 100644 (file)
@@ -1684,14 +1684,8 @@ static void mailbox_copy_cache_decisions_from_inbox(struct mailbox *box)
            existence != MAILBOX_EXISTENCE_NONE &&
            mailbox_open(inbox) == 0 &&
            mailbox_open(box) == 0) {
-               struct mail_index_transaction *dit =
-                       mail_index_transaction_begin(box->view,
-                                                    MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL);
-
-               mail_cache_decisions_copy(dit, inbox->cache, box->cache);
-
                /* we can't do much about errors here */
-               (void)mail_index_transaction_commit(&dit);
+               (void)mail_cache_decisions_copy(inbox->cache, box->cache);
        }
 
        mailbox_free(&inbox);