]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mdbox: Move storage rebuild handling to mdbox_sync()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 3 Jul 2023 09:06:07 +0000 (12:06 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 31 Jan 2024 11:37:41 +0000 (13:37 +0200)
This simplifies the code, since it's the only place that can actually
rebuild the storage. Also will be needed for following commit.

src/lib-storage/index/dbox-multi/mdbox-save.c
src/lib-storage/index/dbox-multi/mdbox-sync.c
src/lib-storage/index/dbox-multi/mdbox-sync.h

index 268f77c7218d8ba3134e091752d1eaae4df43102..6f1853915ce5bb689c10197492b0881e318fd2a3 100644 (file)
@@ -286,6 +286,7 @@ int mdbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
        struct mailbox_transaction_context *_t = _ctx->transaction;
        const struct mail_index_header *hdr;
        uint32_t first_map_uid, last_map_uid;
+       bool corrupted;
 
        i_assert(ctx->ctx.finished);
 
@@ -305,9 +306,12 @@ int mdbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
           up-to-date atomic->sync_view */
        if (mdbox_sync_begin(ctx->mbox, MDBOX_SYNC_FLAG_NO_PURGE |
                             MDBOX_SYNC_FLAG_FORCE |
-                            MDBOX_SYNC_FLAG_FSYNC |
-                            MDBOX_SYNC_FLAG_NO_REBUILD, ctx->atomic,
-                            &ctx->sync_ctx) < 0) {
+                            MDBOX_SYNC_FLAG_FSYNC, ctx->atomic,
+                            &ctx->sync_ctx, &corrupted) < 0) {
+               if (corrupted) {
+                       mailbox_set_critical(_t->box,
+                               "mdbox: Can't rebuild corrupted storage while saving a mail");
+               }
                mdbox_transaction_save_rollback(_ctx);
                return -1;
        }
index 0c2d2d4ce504c4018c23098015501ca83c1ca93c..8b2c55f5227e0ab1a6b278b2b44f5bed5c351682 100644 (file)
@@ -226,30 +226,18 @@ static int mdbox_sync_try_begin(struct mdbox_sync_context *ctx,
 
 int mdbox_sync_begin(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags,
                     struct mdbox_map_atomic_context *atomic,
-                    struct mdbox_sync_context **ctx_r)
+                    struct mdbox_sync_context **ctx_r, bool *corrupted_r)
 {
-       const struct mail_index_header *hdr =
-               mail_index_get_header(mbox->box.view);
        struct mdbox_sync_context *ctx;
        const char *reason;
        enum mail_index_sync_flags sync_flags;
        int ret;
-       bool rebuild, storage_rebuilt = FALSE;
 
        *ctx_r = NULL;
+       *corrupted_r = FALSE;
 
        /* avoid race conditions with mailbox creation, don't check for dbox
           headers until syncing has locked the mailbox */
-       rebuild = mbox->storage->corrupted ||
-               (hdr->flags & MAIL_INDEX_HDR_FLAG_FSCKD) != 0 ||
-               mdbox_map_is_fscked(mbox->storage->map) ||
-               (flags & MDBOX_SYNC_FLAG_FORCE_REBUILD) != 0;
-       if (rebuild && (flags & MDBOX_SYNC_FLAG_NO_REBUILD) == 0) {
-               if (mdbox_storage_rebuild_in_context(mbox->storage, atomic) < 0)
-                       return -1;
-               mailbox_recent_flags_reset(&mbox->box);
-               storage_rebuilt = TRUE;
-       }
 
        ctx = i_new(struct mdbox_sync_context, 1);
        ctx->mbox = mbox;
@@ -257,7 +245,7 @@ int mdbox_sync_begin(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags,
        ctx->atomic = atomic;
 
        sync_flags = index_storage_get_sync_flags(&mbox->box);
-       if (!rebuild && (flags & MDBOX_SYNC_FLAG_FORCE) == 0)
+       if ((flags & MDBOX_SYNC_FLAG_FORCE) == 0)
                sync_flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
        if ((flags & MDBOX_SYNC_FLAG_FSYNC) != 0)
                sync_flags |= MAIL_INDEX_SYNC_FLAG_FSYNC;
@@ -280,25 +268,9 @@ int mdbox_sync_begin(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags,
                index_storage_expunging_deinit(&mbox->box);
                i_free_and_null(ctx);
 
-               if (ret < 0)
-                       return -1;
-
-               /* corrupted */
-               if (storage_rebuilt) {
-                       mailbox_set_critical(&mbox->box,
-                               "mdbox: Storage keeps breaking");
-                       return -1;
-               }
-
-               /* we'll need to rebuild storage.
-                  try again from the beginning. */
-               mdbox_storage_set_corrupted(mbox->storage);
-               if ((flags & MDBOX_SYNC_FLAG_NO_REBUILD) != 0) {
-                       mailbox_set_critical(&mbox->box,
-                               "mdbox: Can't rebuild storage");
-                       return -1;
-               }
-               return mdbox_sync_begin(mbox, flags, atomic, ctx_r);
+               if (ret == 0)
+                       *corrupted_r = TRUE;
+               return -1;
        }
        index_storage_expunging_deinit(&mbox->box);
 
@@ -342,12 +314,43 @@ int mdbox_sync_finish(struct mdbox_sync_context **_ctx, bool success)
 
 int mdbox_sync(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags)
 {
+       const struct mail_index_header *hdr =
+               mail_index_get_header(mbox->box.view);
        struct mdbox_sync_context *sync_ctx;
        struct mdbox_map_atomic_context *atomic;
+       bool corrupted, storage_rebuilt = FALSE;
        int ret;
 
        atomic = mdbox_map_atomic_begin(mbox->storage->map);
-       ret = mdbox_sync_begin(mbox, flags, atomic, &sync_ctx);
+
+       if (mbox->storage->corrupted ||
+           (hdr->flags & MAIL_INDEX_HDR_FLAG_FSCKD) != 0 ||
+           mdbox_map_is_fscked(mbox->storage->map) ||
+           (flags & MDBOX_SYNC_FLAG_FORCE_REBUILD) != 0) {
+               if (mdbox_storage_rebuild_in_context(mbox->storage, atomic) < 0) {
+                       (void)mdbox_map_atomic_finish(&atomic);
+                       return -1;
+               }
+               mailbox_recent_flags_reset(&mbox->box);
+               storage_rebuilt = TRUE;
+               flags |= MDBOX_SYNC_FLAG_FORCE;
+       }
+
+
+       ret = mdbox_sync_begin(mbox, flags, atomic, &sync_ctx, &corrupted);
+       if (corrupted) {
+               if (storage_rebuilt) {
+                       mailbox_set_critical(&mbox->box,
+                               "mdbox: Storage keeps breaking");
+                       return -1;
+               }
+
+               /* we'll need to rebuild storage.
+                  try again from the beginning. */
+               mdbox_storage_set_corrupted(mbox->storage);
+               return mdbox_sync(mbox, flags);
+       }
+
        if (ret == 0 && sync_ctx != NULL)
                ret = mdbox_sync_finish(&sync_ctx, TRUE);
        if (ret == 0)
index a9bc5651f2a86d36c060ec5fee7bab0656484117..8f58bd01e0652f69405ffa0db0b51c9ffd6e4356 100644 (file)
@@ -9,7 +9,6 @@ enum mdbox_sync_flags {
        MDBOX_SYNC_FLAG_FSYNC           = 0x02,
        MDBOX_SYNC_FLAG_FORCE_REBUILD   = 0x04,
        MDBOX_SYNC_FLAG_NO_PURGE        = 0x08,
-       MDBOX_SYNC_FLAG_NO_REBUILD      = 0x10
 };
 
 struct mdbox_sync_context {
@@ -27,7 +26,7 @@ struct mdbox_sync_context {
 
 int mdbox_sync_begin(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags,
                     struct mdbox_map_atomic_context *atomic,
-                    struct mdbox_sync_context **ctx_r);
+                    struct mdbox_sync_context **ctx_r, bool *corrupted_r);
 int mdbox_sync_finish(struct mdbox_sync_context **ctx, bool success);
 int mdbox_sync(struct mdbox_mailbox *mbox, enum mdbox_sync_flags flags);