]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Transaction commits can now track how many uid/modseq updates were ignored.
authorTimo Sirainen <tss@iki.fi>
Thu, 19 Nov 2009 00:58:07 +0000 (19:58 -0500)
committerTimo Sirainen <tss@iki.fi>
Thu, 19 Nov 2009 00:58:07 +0000 (19:58 -0500)
--HG--
branch : HEAD

22 files changed:
src/lib-index/mail-cache-transaction.c
src/lib-index/mail-index-modseq.c
src/lib-index/mail-index-private.h
src/lib-index/mail-index-sync-update.c
src/lib-index/mail-index-sync.c
src/lib-index/mail-index-transaction-private.h
src/lib-index/mail-index-transaction.c
src/lib-index/mail-index.h
src/lib-storage/index/cydir/cydir-save.c
src/lib-storage/index/cydir/cydir-storage.h
src/lib-storage/index/dbox-multi/mdbox-save.c
src/lib-storage/index/dbox-multi/mdbox-storage.h
src/lib-storage/index/dbox-single/sdbox-save.c
src/lib-storage/index/dbox-single/sdbox-storage.h
src/lib-storage/index/index-storage.h
src/lib-storage/index/index-transaction.c
src/lib-storage/index/maildir/maildir-save.c
src/lib-storage/index/maildir/maildir-storage.h
src/lib-storage/index/mbox/mbox-save.c
src/lib-storage/index/mbox/mbox-storage.h
src/lib-storage/list/index-mailbox-list-sync.c
src/lib-storage/mail-storage.h

index 5d683b314929e9751b0c14778a7811ff6a080544..7654ae3245fa24b614c05683cce8f12145ee8e03 100644 (file)
@@ -68,14 +68,13 @@ static void mail_index_transaction_cache_reset(struct mail_index_transaction *t)
 
 static int
 mail_index_transaction_cache_commit(struct mail_index_transaction *t,
-                                   uint32_t *log_file_seq_r,
-                                   uoff_t *log_file_offset_r)
+                                   struct mail_index_transaction_commit_result *result_r)
 {
        struct mail_cache_transaction_ctx *ctx = CACHE_TRANS_CONTEXT(t);
        struct mail_index_transaction_vfuncs super = ctx->super;
 
        mail_cache_transaction_commit(&ctx);
-       return super.commit(t, log_file_seq_r, log_file_offset_r);
+       return super.commit(t, result_r);
 }
 
 static void
index 8fa94abda92b5a85b35df6b94ce1167dcdba3880..ca54e5f36e5fd834bcae3d03a4dec2cd0c3c19c0 100644 (file)
@@ -202,9 +202,12 @@ int mail_index_modseq_set(struct mail_index_view *view,
 
        ext = array_idx(&view->map->extensions, ext_map_idx);
        modseqp = PTR_OFFSET(rec, ext->record_offset);
-       if (*modseqp < min_modseq)
+       if (*modseqp > min_modseq)
+               return 0;
+       else {
                *modseqp = min_modseq;
-       return 0;
+               return 1;
+       }
 }
 
 static uint64_t
index c607eaf299bc9f8bd5738b5c2ff9bf8816de0823..da66b58ba7177c6967d934b0250f0ba9b2511b47 100644 (file)
@@ -201,6 +201,9 @@ struct mail_index {
        uint32_t fsck_log_head_file_seq;
        uoff_t fsck_log_head_file_offset;
 
+       /* syncing will update this if non-NULL */
+       struct mail_index_transaction_commit_result *sync_commit_result;
+
        int lock_type, shared_lock_count, excl_lock_count;
        unsigned int lock_id_counter;
        enum file_lock_method lock_method;
index 7829981234fa7e70033f2910adb4da214606e063..0a9f07f174d5b338a29c141f942a4a07ad07e39f 100644 (file)
@@ -279,9 +279,32 @@ static void *sync_append_record(struct mail_index_map *map)
        return ret;
 }
 
+static bool sync_update_ignored_change(struct mail_index_sync_map_ctx *ctx)
+{
+       struct mail_index_transaction_commit_result *result =
+               ctx->view->index->sync_commit_result;
+       uint32_t log_seq;
+       uoff_t log_offset, start_offset;
+
+       if (result == NULL)
+               return FALSE;
+
+       mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
+                                              &log_seq, &log_offset);
+       if (log_seq != result->log_file_seq)
+               return FALSE;
+
+       start_offset = result->log_file_offset - result->commit_size;
+       if (log_offset < start_offset || log_offset >= result->log_file_offset)
+               return FALSE;
+
+       return TRUE;
+}
+
 static void sync_uid_update(struct mail_index_sync_map_ctx *ctx,
                            uint32_t old_uid, uint32_t new_uid)
 {
+       struct mail_index_view *view = ctx->view;
        struct mail_index_map *map;
        struct mail_index_record *rec;
        uint32_t old_seq;
@@ -289,10 +312,12 @@ static void sync_uid_update(struct mail_index_sync_map_ctx *ctx,
 
        if (new_uid < ctx->view->map->hdr.next_uid) {
                /* uid update is no longer possible */
+               if (sync_update_ignored_change(ctx))
+                       view->index->sync_commit_result->ignored_uid_changes++;
                return;
        }
 
-       if (!mail_index_lookup_seq(ctx->view, old_uid, &old_seq))
+       if (!mail_index_lookup_seq(view, old_uid, &old_seq))
                return;
 
        map = mail_index_sync_get_atomic_map(ctx);
@@ -320,6 +345,7 @@ sync_modseq_update(struct mail_index_sync_map_ctx *ctx,
        const struct mail_transaction_modseq_update *end;
        uint32_t seq;
        uint64_t min_modseq, highest_modseq = 0;
+       int ret;
 
        end = CONST_PTR_OFFSET(u, size);
        for (; u < end; u++) {
@@ -332,12 +358,16 @@ sync_modseq_update(struct mail_index_sync_map_ctx *ctx,
                        u->modseq_low32;
                if (highest_modseq < min_modseq)
                        highest_modseq = min_modseq;
-               if (seq != 0 &&
-                   mail_index_modseq_set(view, seq, min_modseq) < 0) {
+
+               ret = seq == 0 ? 1 :
+                       mail_index_modseq_set(view, seq, min_modseq);
+               if (ret < 0) {
                        mail_index_sync_set_corrupted(ctx,
                                "modseqs updated before they were enabled");
                        return -1;
                }
+               if (ret == 0 && sync_update_ignored_change(ctx))
+                       view->index->sync_commit_result->ignored_modseq_changes++;
        }
 
        mail_index_modseq_update_highest(ctx->modseq_ctx, highest_modseq);
index 78eee8eafed004d17441b5be4cd50e605c561123..0c7f1aeb4e27aabdfe595a8b5203a4512d8ccf1a 100644 (file)
@@ -15,6 +15,7 @@ struct mail_index_sync_ctx {
        struct mail_index *index;
        struct mail_index_view *view;
        struct mail_index_transaction *sync_trans, *ext_trans;
+       struct mail_index_transaction_commit_result *sync_commit_result;
        enum mail_index_sync_flags flags;
 
        const struct mail_transaction_header *hdr;
@@ -688,6 +689,12 @@ bool mail_index_sync_have_more(struct mail_index_sync_ctx *ctx)
        return FALSE;
 }
 
+void mail_index_sync_set_commit_result(struct mail_index_sync_ctx *ctx,
+                                      struct mail_index_transaction_commit_result *result)
+{
+       ctx->sync_commit_result = result;
+}
+
 void mail_index_sync_reset(struct mail_index_sync_ctx *ctx)
 {
        struct mail_index_sync_list *sync_list;
@@ -787,8 +794,10 @@ int mail_index_sync_commit(struct mail_index_sync_ctx **_ctx)
        /* refresh the mapping with newly committed external transactions
           and the synced expunges. sync using file handler here so that the
           expunge handlers get called. */
+       index->sync_commit_result = ctx->sync_commit_result;
        if (mail_index_map(ctx->index, MAIL_INDEX_SYNC_HANDLER_FILE) <= 0)
                ret = -1;
+       index->sync_commit_result = NULL;
 
        want_rotate = mail_transaction_log_want_rotate(index->log);
        if (ret == 0 &&
index a0cd0af78a1167b5005350367282487f832cae7e..e39d5e3ca42f5f634fc44d471abaf6b0f8a9949e 100644 (file)
@@ -21,7 +21,7 @@ struct mail_index_transaction_ext_hdr_update {
 struct mail_index_transaction_vfuncs {
        void (*reset)(struct mail_index_transaction *t);
        int (*commit)(struct mail_index_transaction *t,
-                     uint32_t *log_file_seq_r, uoff_t *log_file_offset_r);
+                     struct mail_index_transaction_commit_result *result_r);
        void (*rollback)(struct mail_index_transaction *t);
 };
 
index 6dc4d7d12c78d2e31876fb8169c4b31d3f31ad29..c42ebfc2bdc454616bb18d8a8a5edf0bbe6a34de 100644 (file)
@@ -120,7 +120,9 @@ mail_transaction_log_file_refresh(struct mail_index_transaction *t,
        return 1;
 }
 
-static int mail_index_transaction_commit_real(struct mail_index_transaction *t)
+static int
+mail_index_transaction_commit_real(struct mail_index_transaction *t,
+                                  uoff_t *commit_size_r)
 {
        struct mail_transaction_log *log = t->view->index->log;
        bool external = (t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0;
@@ -144,6 +146,8 @@ static int mail_index_transaction_commit_real(struct mail_index_transaction *t)
        mail_transaction_log_get_head(log, &log_seq2, &log_offset2);
        i_assert(log_seq1 == log_seq2);
 
+       *commit_size_r = log_offset2 - log_offset1;
+
        if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_HIDE) != 0 &&
            log_offset1 != log_offset2) {
                /* mark the area covered by this transaction hidden */
@@ -154,8 +158,7 @@ static int mail_index_transaction_commit_real(struct mail_index_transaction *t)
 }
 
 static int mail_index_transaction_commit_v(struct mail_index_transaction *t,
-                                          uint32_t *log_file_seq_r,
-                                          uoff_t *log_file_offset_r)
+                                          struct mail_index_transaction_commit_result *result_r)
 {
        struct mail_index *index = t->view->index;
        bool changed;
@@ -165,14 +168,10 @@ static int mail_index_transaction_commit_v(struct mail_index_transaction *t,
                 mail_index_view_get_messages_count(t->view));
 
        changed = MAIL_INDEX_TRANSACTION_HAS_CHANGES(t) || t->reset;
-       if (!changed) {
-               /* nothing to append */
-               ret = 0;
-       } else {
-               ret = mail_index_transaction_commit_real(t);
-       }
-       mail_transaction_log_get_head(index->log, log_file_seq_r,
-                                     log_file_offset_r);
+       ret = !changed ? 0 :
+               mail_index_transaction_commit_real(t, &result_r->commit_size);
+       mail_transaction_log_get_head(index->log, &result_r->log_file_seq,
+                                     &result_r->log_file_offset);
 
        if (ret == 0 && !index->syncing && changed) {
                /* if we're committing a normal transaction, we want to
@@ -184,7 +183,9 @@ static int mail_index_transaction_commit_v(struct mail_index_transaction *t,
                   be done later as MAIL_INDEX_SYNC_HANDLER_FILE so that
                   expunge handlers get run for the newly expunged messages
                   (and sync handlers that require HANDLER_FILE as well). */
+               index->sync_commit_result = result_r;
                (void)mail_index_refresh(index);
+               index->sync_commit_result = NULL;
        }
 
        mail_index_transaction_unref(&t);
@@ -198,15 +199,13 @@ static void mail_index_transaction_rollback_v(struct mail_index_transaction *t)
 
 int mail_index_transaction_commit(struct mail_index_transaction **t)
 {
-       uint32_t log_seq;
-       uoff_t log_offset;
+       struct mail_index_transaction_commit_result result;
 
-       return mail_index_transaction_commit_get_pos(t, &log_seq, &log_offset);
+       return mail_index_transaction_commit_full(t, &result);
 }
 
-int mail_index_transaction_commit_get_pos(struct mail_index_transaction **_t,
-                                         uint32_t *log_file_seq_r,
-                                         uoff_t *log_file_offset_r)
+int mail_index_transaction_commit_full(struct mail_index_transaction **_t,
+                                      struct mail_index_transaction_commit_result *result_r)
 {
        struct mail_index_transaction *t = *_t;
 
@@ -216,7 +215,8 @@ int mail_index_transaction_commit_get_pos(struct mail_index_transaction **_t,
        }
 
        *_t = NULL;
-       return t->v.commit(t, log_file_seq_r, log_file_offset_r);
+       memset(result_r, 0, sizeof(*result_r));
+       return t->v.commit(t, result_r);
 }
 
 void mail_index_transaction_rollback(struct mail_index_transaction **_t)
index 8bbfe8bf39bb14020d0b9f117e52303e31dd6008..1ef56606ee07904ae8f309cb3903b2f6d7a273f4 100644 (file)
@@ -183,6 +183,18 @@ struct mail_index_view_sync_rec {
        unsigned int hidden:1;
 };
 
+struct mail_index_transaction_commit_result {
+       /* seq/offset points to end of transaction */
+       uint32_t log_file_seq;
+       uoff_t log_file_offset;
+       /* number of bytes in the written transaction.
+          all of it was written to the same file. */
+       uoff_t commit_size;
+
+       unsigned int ignored_uid_changes;
+       unsigned int ignored_modseq_changes;
+};
+
 struct mail_index;
 struct mail_index_map;
 struct mail_index_view;
@@ -245,9 +257,8 @@ struct mail_index_transaction *
 mail_index_transaction_begin(struct mail_index_view *view,
                             enum mail_index_transaction_flags flags);
 int mail_index_transaction_commit(struct mail_index_transaction **t);
-int mail_index_transaction_commit_get_pos(struct mail_index_transaction **t,
-                                         uint32_t *log_file_seq_r,
-                                         uoff_t *log_file_offset_r);
+int mail_index_transaction_commit_full(struct mail_index_transaction **t,
+                                      struct mail_index_transaction_commit_result *result_r);
 void mail_index_transaction_rollback(struct mail_index_transaction **t);
 /* Discard all changes in the transaction. */
 void mail_index_transaction_reset(struct mail_index_transaction *t);
@@ -326,6 +337,9 @@ bool mail_index_sync_have_more(struct mail_index_sync_ctx *ctx);
 /* Reset syncing to initial state after mail_index_sync_begin(), so you can
    go through all the sync records again with mail_index_sync_next(). */
 void mail_index_sync_reset(struct mail_index_sync_ctx *ctx);
+/* Update result when refreshing index at the end of sync. */
+void mail_index_sync_set_commit_result(struct mail_index_sync_ctx *ctx,
+                                      struct mail_index_transaction_commit_result *result);
 /* Commit synchronization by writing all changes to mail index file. */
 int mail_index_sync_commit(struct mail_index_sync_ctx **ctx);
 /* Rollback synchronization - none of the changes listed by sync_next() are
index e7d44373187ab2f3f8d036496bcfd5809dba1e9b..0276ac463b21ea60bfb82f97761cc0990174781c 100644 (file)
@@ -292,12 +292,16 @@ int cydir_transaction_save_commit_pre(struct mail_save_context *_ctx)
        return 0;
 }
 
-void cydir_transaction_save_commit_post(struct mail_save_context *_ctx)
+void cydir_transaction_save_commit_post(struct mail_save_context *_ctx,
+                                       struct mail_index_transaction_commit_result *result)
 {
        struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
 
        _ctx->transaction = NULL; /* transaction is already freed */
 
+       mail_index_sync_set_commit_result(ctx->sync_ctx->index_sync_ctx,
+                                         result);
+
        (void)cydir_sync_finish(&ctx->sync_ctx, TRUE);
        cydir_transaction_save_rollback(_ctx);
 }
index 3d1f657bf986838350f481972f84db4c5627ac9b..682740a42833e2315ecfa743863b91f6324127fb 100644 (file)
@@ -29,7 +29,8 @@ int cydir_save_finish(struct mail_save_context *ctx);
 void cydir_save_cancel(struct mail_save_context *ctx);
 
 int cydir_transaction_save_commit_pre(struct mail_save_context *ctx);
-void cydir_transaction_save_commit_post(struct mail_save_context *ctx);
+void cydir_transaction_save_commit_post(struct mail_save_context *ctx,
+                                       struct mail_index_transaction_commit_result *result);
 void cydir_transaction_save_rollback(struct mail_save_context *ctx);
 
 #endif
index 781e6e9731070eb3e0714b71a3a6295edd3586e0..4a9d93a03ea3391642efcabfd0a59cd36dc417a2 100644 (file)
@@ -266,12 +266,16 @@ int mdbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
        return 0;
 }
 
-void mdbox_transaction_save_commit_post(struct mail_save_context *_ctx)
+void mdbox_transaction_save_commit_post(struct mail_save_context *_ctx,
+                                       struct mail_index_transaction_commit_result *result)
 {
        struct mdbox_save_context *ctx = (struct mdbox_save_context *)_ctx;
 
        _ctx->transaction = NULL; /* transaction is already freed */
 
+       mail_index_sync_set_commit_result(ctx->sync_ctx->index_sync_ctx,
+                                         result);
+
        /* finish writing the mailbox APPENDs */
        if (mdbox_sync_finish(&ctx->sync_ctx, TRUE) == 0) {
                if (ctx->map_trans != NULL)
index 2a40953767f971fc7bb1dec2ae44a38a441a7207..b937f0194d2cf7f10174f97ee70f8c2c0fdf4e38 100644 (file)
@@ -78,7 +78,8 @@ mdbox_save_file_get_file(struct mailbox_transaction_context *t,
                         uint32_t seq, uoff_t *offset_r);
 
 int mdbox_transaction_save_commit_pre(struct mail_save_context *ctx);
-void mdbox_transaction_save_commit_post(struct mail_save_context *ctx);
+void mdbox_transaction_save_commit_post(struct mail_save_context *ctx,
+                                       struct mail_index_transaction_commit_result *result);
 void mdbox_transaction_save_rollback(struct mail_save_context *ctx);
 
 int mdbox_copy(struct mail_save_context *ctx, struct mail *mail);
index b0fb72c3a49f11919bb3a60a70e06ce3d31aa6e5..ed3bf5dc7fedd3a920be0e39bf8e20d272362a41 100644 (file)
@@ -246,7 +246,8 @@ int sdbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
        return 0;
 }
 
-void sdbox_transaction_save_commit_post(struct mail_save_context *_ctx)
+void sdbox_transaction_save_commit_post(struct mail_save_context *_ctx,
+                                       struct mail_index_transaction_commit_result *result)
 {
        struct sdbox_save_context *ctx = (struct sdbox_save_context *)_ctx;
 
@@ -257,6 +258,9 @@ void sdbox_transaction_save_commit_post(struct mail_save_context *_ctx)
                return;
        }
 
+       mail_index_sync_set_commit_result(ctx->sync_ctx->index_sync_ctx,
+                                         result);
+
        if (sdbox_sync_finish(&ctx->sync_ctx, TRUE) < 0)
                ctx->ctx.failed = TRUE;
 
index 79f35f7e4ce382ced5f61c6c3da6b416bd93f35e..34148a30dd3f719451c398062d29adfb3c1c337b 100644 (file)
@@ -61,7 +61,8 @@ struct dbox_file *
 sdbox_save_file_get_file(struct mailbox_transaction_context *t, uint32_t seq);
 
 int sdbox_transaction_save_commit_pre(struct mail_save_context *ctx);
-void sdbox_transaction_save_commit_post(struct mail_save_context *ctx);
+void sdbox_transaction_save_commit_post(struct mail_save_context *ctx,
+                                       struct mail_index_transaction_commit_result *result);
 void sdbox_transaction_save_rollback(struct mail_save_context *ctx);
 
 int sdbox_copy(struct mail_save_context *ctx, struct mail *mail);
index 8a6a72e0acdeb8044a304ecc2e8233f3c954e4ad..c7c2013dfa1a1c85631425b78f743326e68e28b0 100644 (file)
@@ -35,7 +35,8 @@ struct index_mailbox {
        enum mail_index_open_flags index_flags;
 
        int (*save_commit_pre)(struct mail_save_context *save_ctx);
-       void (*save_commit_post)(struct mail_save_context *save_ctx);
+       void (*save_commit_post)(struct mail_save_context *save_ctx,
+                                struct mail_index_transaction_commit_result *result_r);
        void (*save_rollback)(struct mail_save_context *save_ctx);
 
        struct mail_index *index;
index 706c67e7a0f76b9b41f02761ffd21abd173599f1..e0ba7541b20701685702bc81cd37d02c7ca28a62 100644 (file)
@@ -15,8 +15,7 @@ static void index_transaction_free(struct index_transaction_context *t)
 
 static int
 index_transaction_index_commit(struct mail_index_transaction *index_trans,
-                              uint32_t *log_file_seq_r,
-                              uoff_t *log_file_offset_r)
+                              struct mail_index_transaction_commit_result *result_r)
 {
        struct index_transaction_context *it =
                MAIL_STORAGE_CONTEXT(index_trans);
@@ -35,15 +34,14 @@ index_transaction_index_commit(struct mail_index_transaction *index_trans,
        if (ret < 0)
                it->super.rollback(it->trans);
        else {
-               if (it->super.commit(it->trans, log_file_seq_r,
-                                    log_file_offset_r) < 0) {
+               if (it->super.commit(it->trans, result_r) < 0) {
                        mail_storage_set_index_error(ibox);
                        ret = -1;
                }
        }
 
        if (t->save_ctx != NULL)
-               ibox->save_commit_post(t->save_ctx);
+               ibox->save_commit_post(t->save_ctx, result_r);
 
        index_transaction_free(it);
        return ret;
@@ -115,15 +113,19 @@ int index_transaction_commit(struct mailbox_transaction_context *_t,
                (struct index_transaction_context *)_t;
        struct mail_index_transaction *itrans = t->trans;
        struct index_mailbox *ibox = (struct index_mailbox *)_t->box;
+       struct mail_index_transaction_commit_result result;
        int ret;
 
        memset(changes_r, 0, sizeof(*changes_r));
        changes_r->pool = pool_alloconly_create("transaction changes", 1024);
        p_array_init(&changes_r->saved_uids, changes_r->pool, 32);
-       p_array_init(&changes_r->updated_uids, changes_r->pool, 32);
        _t->changes = changes_r;
 
-       ret = mail_index_transaction_commit(&itrans);
+       ret = mail_index_transaction_commit_full(&itrans, &result);
+
+       changes_r->ignored_uid_changes = result.ignored_uid_changes;
+       changes_r->ignored_modseq_changes = result.ignored_modseq_changes;
+
        i_assert(ibox->box.transaction_count > 0 ||
                 ibox->view->transactions == 0);
        return ret;
index 25a3e2c0979ba33f891cacb9a10f2b21ee8eb894..55592148ed1af700178be6caab855523d8d88dbe 100644 (file)
@@ -971,7 +971,8 @@ int maildir_transaction_save_commit_pre(struct mail_save_context *_ctx)
        return 0;
 }
 
-void maildir_transaction_save_commit_post(struct mail_save_context *_ctx)
+void maildir_transaction_save_commit_post(struct mail_save_context *_ctx,
+                                         struct mail_index_transaction_commit_result *result ATTR_UNUSED)
 {
        struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
 
index cb170bb0797dcceff3835e7f42507a50006a22ae..240f151346172cf6c430c8760434c2bbd054f0c7 100644 (file)
@@ -131,7 +131,8 @@ const char *maildir_save_file_get_path(struct mailbox_transaction_context *t,
                                       uint32_t seq);
 
 int maildir_transaction_save_commit_pre(struct mail_save_context *ctx);
-void maildir_transaction_save_commit_post(struct mail_save_context *ctx);
+void maildir_transaction_save_commit_post(struct mail_save_context *ctx,
+                                         struct mail_index_transaction_commit_result *result);
 void maildir_transaction_save_rollback(struct mail_save_context *ctx);
 
 int maildir_copy(struct mail_save_context *ctx, struct mail *mail);
index 467db1c47e490716b2351f45f6fa173129711230..67f1fafb4e134b2ff267cfd4be1de5aa8847571e 100644 (file)
@@ -796,7 +796,8 @@ int mbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
        return ret;
 }
 
-void mbox_transaction_save_commit_post(struct mail_save_context *_ctx)
+void mbox_transaction_save_commit_post(struct mail_save_context *_ctx,
+                                      struct mail_index_transaction_commit_result *result ATTR_UNUSED)
 {
        struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
 
index 11e89ace4c0fd0ae634a6e879d2d6367d9f802c1..b1c25cca3c98d69a4b6466e1dcc18a99c677bfab 100644 (file)
@@ -83,7 +83,8 @@ int mbox_save_finish(struct mail_save_context *ctx);
 void mbox_save_cancel(struct mail_save_context *ctx);
 
 int mbox_transaction_save_commit_pre(struct mail_save_context *ctx);
-void mbox_transaction_save_commit_post(struct mail_save_context *ctx);
+void mbox_transaction_save_commit_post(struct mail_save_context *ctx,
+                                      struct mail_index_transaction_commit_result *result);
 void mbox_transaction_save_rollback(struct mail_save_context *ctx);
 
 #endif
index ee6e8fea519d0b5e66c881e30d39ffcc004b82ac..5543fa5dbc1a6af0edede18a25085983304246de 100644 (file)
@@ -219,6 +219,7 @@ index_list_update(struct index_mailbox_list *ilist, struct mailbox *box,
 {
        struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
        struct mail_index_transaction *trans;
+       struct mail_index_transaction_commit_result result;
        const void *data;
        const uint32_t *counter_p;
        uint32_t *ext_id_p;
@@ -254,8 +255,12 @@ index_list_update(struct index_mailbox_list *ilist, struct mailbox *box,
                return -1;
        }
 
-       return mail_index_transaction_commit_get_pos(&trans, &ibox->log_seq,
-                                                    &ibox->log_offset);
+       if (mail_index_transaction_commit_full(&trans, &result) < 0)
+               return -1;
+
+       ibox->log_seq = result.log_file_seq;
+       ibox->log_offset = result.log_file_offset;
+       return 0;
 }
 
 static struct mailbox_sync_context *
index 98625853019df7930ed855dcbe3f8730f201e3bf..f58e784553422d716084f340cd6beabdb8400429 100644 (file)
@@ -213,9 +213,10 @@ struct mail_transaction_commit_changes {
        uint32_t uid_validity;
        /* UIDs assigned to saved messages. Not necessarily ascending. */
        ARRAY_TYPE(seq_range) saved_uids;
-       /* UIDs assigned to updated UIDs. Not necessarily the same as the
-          requested new UIDs. */
-       ARRAY_TYPE(seq_range) updated_uids;
+
+       /* number of uid/modseq changes that couldn't be changed as requested */
+       unsigned int ignored_uid_changes;
+       unsigned int ignored_modseq_changes;
 };
 
 struct mailbox_sync_rec {