From: Timo Sirainen Date: Mon, 12 Aug 2013 14:24:05 +0000 (+0300) Subject: lib-storage: If dovecot.index.thread corruption is noticed, delete the file. X-Git-Tag: 2.2.6~135 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f24202d1a342ac63fb8c28e6fa74e16d37f29ca3;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: If dovecot.index.thread corruption is noticed, delete the file. --- diff --git a/src/lib-index/mail-index-strmap.c b/src/lib-index/mail-index-strmap.c index ee358e90c9..654d99218d 100644 --- a/src/lib-index/mail-index-strmap.c +++ b/src/lib-index/mail-index-strmap.c @@ -238,8 +238,7 @@ static void mail_index_strmap_view_reset(struct mail_index_strmap_view *view) view->desynced = FALSE; } -static void -mail_index_strmap_view_set_corrupted(struct mail_index_strmap_view *view) +void mail_index_strmap_view_set_corrupted(struct mail_index_strmap_view *view) { mail_index_set_error(view->strmap->index, "Corrupted strmap index file: %s", diff --git a/src/lib-index/mail-index-strmap.h b/src/lib-index/mail-index-strmap.h index 69e1cbd848..8b992affad 100644 --- a/src/lib-index/mail-index-strmap.h +++ b/src/lib-index/mail-index-strmap.h @@ -56,6 +56,7 @@ mail_index_strmap_view_open(struct mail_index_strmap *strmap, const ARRAY_TYPE(mail_index_strmap_rec) **recs_r, const struct hash2_table **hash_r); void mail_index_strmap_view_close(struct mail_index_strmap_view **view); +void mail_index_strmap_view_set_corrupted(struct mail_index_strmap_view *view); /* Return the highest used string index. */ uint32_t mail_index_strmap_view_get_highest_idx(struct mail_index_strmap_view *view); diff --git a/src/lib-storage/index/index-thread.c b/src/lib-storage/index/index-thread.c index 65b5d13f1e..5f19d0874d 100644 --- a/src/lib-storage/index/index-thread.c +++ b/src/lib-storage/index/index-thread.c @@ -28,6 +28,7 @@ struct mail_thread_context { ARRAY_TYPE(seq_range) added_uids; unsigned int failed:1; + unsigned int corrupted:1; }; struct mail_thread_mailbox { @@ -52,10 +53,11 @@ static MODULE_CONTEXT_DEFINE_INIT(mail_thread_storage_module, static void mail_thread_clear(struct mail_thread_context *ctx); static int -mail_strmap_rec_get_msgid(struct mail *mail, +mail_strmap_rec_get_msgid(struct mail_thread_context *ctx, const struct mail_index_strmap_rec *rec, const char **msgid_r) { + struct mail *mail = ctx->tmp_mail; const char *msgids = NULL, *msgid; unsigned int n = 0; int ret; @@ -91,15 +93,18 @@ mail_strmap_rec_get_msgid(struct mail *mail, /* get the nth message-id */ msgid = message_id_get_next(&msgids); if (msgid != NULL) { - for (; n > 0 && *msgids != '\0'; n--) + for (; n > 0; n--) msgid = message_id_get_next(&msgids); } if (msgid == NULL) { - /* shouldn't have happened */ + /* shouldn't have happened, probably corrupted */ mail_storage_set_critical(mail->box->storage, - "Threading in %s UID %u lost Message ID %u", + "Corrupted thread index for mailbox %s: " + "UID %u lost Message ID %u", mail->box->vname, mail->uid, rec->ref_index); + ctx->failed = TRUE; + ctx->corrupted = TRUE; return -1; } *msgid_r = msgid; @@ -119,7 +124,7 @@ mail_thread_hash_key_cmp(const char *key, /* either a match or a collision, need to look closer */ T_BEGIN { - ret = mail_strmap_rec_get_msgid(ctx->tmp_mail, rec, &msgid); + ret = mail_strmap_rec_get_msgid(ctx, rec, &msgid); if (ret <= 0) { if (ret < 0) ctx->failed = TRUE; @@ -142,11 +147,10 @@ mail_thread_hash_rec_cmp(const struct mail_index_strmap_rec *rec1, int ret; T_BEGIN { - ret = mail_strmap_rec_get_msgid(ctx->tmp_mail, rec1, &msgid1); + ret = mail_strmap_rec_get_msgid(ctx, rec1, &msgid1); if (ret > 0) { msgid1 = t_strdup(msgid1); - ret = mail_strmap_rec_get_msgid(ctx->tmp_mail, rec2, - &msgid2); + ret = mail_strmap_rec_get_msgid(ctx, rec2, &msgid2); } ret = ret <= 0 ? -1 : strcmp(msgid1, msgid2) == 0; @@ -567,7 +571,11 @@ int mail_thread_init(struct mailbox *box, struct mail_search_args *args, mail_thread_cache_sync_add(tbox, ctx, search_ctx); if (mailbox_search_deinit(&search_ctx) < 0) ret = -1; - + if (ctx->failed) { + ret = -1; + if (ctx->corrupted) + mail_index_strmap_view_set_corrupted(tbox->strmap_view); + } if (ret < 0) { mail_thread_deinit(&ctx); return -1;