From: Timo Sirainen Date: Mon, 3 Jul 2023 20:36:31 +0000 (+0300) Subject: mdbox: Skip storage rebuild if the reason for it no longer exists after locking map X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8a64816c3de07d210199b01b064f4b9d2d6c8dde;p=thirdparty%2Fdovecot%2Fcore.git mdbox: Skip storage rebuild if the reason for it no longer exists after locking map --- diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c index 96379287a9..d560465975 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c @@ -899,6 +899,16 @@ mdbox_storage_rebuild_scan_dir(struct mdbox_storage_rebuild_context *ctx, return ret; } +static bool mdbox_mailbox_is_fscked(struct mailbox *box) +{ + (void)mail_index_refresh(box->index); + struct mail_index_view *view = mail_index_view_open(box->index); + const struct mail_index_header *hdr = mail_index_get_header(box->view); + bool fscked = (hdr->flags & MAIL_INDEX_HDR_FLAG_FSCKD) != 0; + mail_index_view_close(&view); + return fscked; +} + static int mdbox_storage_rebuild_scan_prepare(struct mdbox_storage_rebuild_context *ctx, struct mailbox *fsckd_box, @@ -916,20 +926,28 @@ mdbox_storage_rebuild_scan_prepare(struct mdbox_storage_rebuild_context *ctx, if (mdbox_map_atomic_lock(ctx->atomic, "mdbox storage rebuild") < 0) return -1; + /* get storage rebuild counter after locking */ + ctx->rebuild_count = mdbox_map_get_rebuild_count(ctx->storage->map); + if ((reason & MDBOX_REBUILD_REASON_FORCED) != 0) *reason_string_r = "Rebuild forced"; - else if ((reason & MDBOX_REBUILD_REASON_CORRUPTED) != 0) { + else if ((reason & MDBOX_REBUILD_REASON_CORRUPTED) != 0 && + ctx->rebuild_count == ctx->storage->corrupted_rebuild_count) { i_assert(ctx->storage->corrupted_reason != NULL); *reason_string_r = t_strdup_printf( "Storage was marked corrupted: %s", ctx->storage->corrupted_reason); - } else if ((reason & MDBOX_REBUILD_REASON_MAP_FSCKD) != 0) + } else if ((reason & MDBOX_REBUILD_REASON_MAP_FSCKD) != 0 && + mdbox_map_refresh(ctx->storage->map) == 0 && + mdbox_map_is_fscked(ctx->storage->map)) *reason_string_r = "dovecot.index.map was fsck'd"; - else if ((reason & MDBOX_REBUILD_REASON_MAILBOX_FSCKD) != 0) { + else if ((reason & MDBOX_REBUILD_REASON_MAILBOX_FSCKD) != 0 && + mdbox_mailbox_is_fscked(fsckd_box)) { *reason_string_r = t_strdup_printf( "Mailbox %s index was fsck'd", fsckd_box->vname); } else { - i_unreached(); + /* storage was already rebuilt by someone else */ + return 0; } /* fsck the map just in case its UIDs are broken */ @@ -947,14 +965,6 @@ mdbox_storage_rebuild_scan_prepare(struct mdbox_storage_rebuild_context *ctx, memcpy(&ctx->orig_map_hdr, data, I_MIN(data_size, sizeof(ctx->orig_map_hdr))); ctx->highest_file_id = ctx->orig_map_hdr.highest_file_id; - - /* get storage rebuild counter after locking */ - ctx->rebuild_count = mdbox_map_get_rebuild_count(ctx->storage->map); - if (ctx->rebuild_count != ctx->storage->corrupted_rebuild_count && - ctx->storage->corrupted_reason != NULL) { - /* storage was already rebuilt by someone else */ - return 0; - } return 1; }