From: Timo Sirainen Date: Tue, 2 Mar 2010 14:12:44 +0000 (+0200) Subject: [m]dbox: Fixes to rebuilding a broken index. X-Git-Tag: 2.0.beta4~140 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9501bf6eb32d734779cc4ddd919f3790b87466c0;p=thirdparty%2Fdovecot%2Fcore.git [m]dbox: Fixes to rebuilding a broken index. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-common/dbox-sync-rebuild.c b/src/lib-storage/index/dbox-common/dbox-sync-rebuild.c index fa7fb9ca13..98d3608f31 100644 --- a/src/lib-storage/index/dbox-common/dbox-sync-rebuild.c +++ b/src/lib-storage/index/dbox-common/dbox-sync-rebuild.c @@ -2,6 +2,7 @@ #include "lib.h" #include "array.h" +#include "mail-index-modseq.h" #include "index-storage.h" #include "dbox-storage.h" #include "dbox-sync-rebuild.h" @@ -50,6 +51,7 @@ dbox_sync_index_copy_from_old(struct dbox_sync_rebuild_context *ctx, const struct mail_index_record *rec; ARRAY_TYPE(keyword_indexes) old_keywords; struct mail_keywords *kw; + uint64_t modseq; /* copy flags */ rec = mail_index_lookup(view, old_seq); @@ -63,6 +65,10 @@ dbox_sync_index_copy_from_old(struct dbox_sync_rebuild_context *ctx, mail_index_update_keywords(ctx->trans, new_seq, MODIFY_REPLACE, kw); mail_index_keywords_unref(&kw); + /* copy modseq */ + modseq = mail_index_modseq_lookup(view, old_seq); + mail_index_update_modseq(ctx->trans, new_seq, modseq); + dbox_sync_index_copy_cache(ctx, view, old_seq, new_seq); } @@ -83,6 +89,47 @@ void dbox_sync_rebuild_index_metadata(struct dbox_sync_rebuild_context *ctx, } } +static void dbox_sync_rebuild_header(struct dbox_sync_rebuild_context *ctx) +{ + const struct mail_index_header *hdr, *backup_hdr; + uint32_t uid_validity, next_uid; + + hdr = mail_index_get_header(ctx->view); + backup_hdr = ctx->backup_view == NULL ? NULL : + mail_index_get_header(ctx->backup_view); + + /* set uidvalidity */ + if (hdr->uid_validity != 0) + uid_validity = hdr->uid_validity; + else if (backup_hdr != NULL && backup_hdr->uid_validity != 0) + uid_validity = backup_hdr->uid_validity; + else + uid_validity = dbox_get_uidvalidity_next(ctx->box->list); + mail_index_update_header(ctx->trans, + offsetof(struct mail_index_header, uid_validity), + &uid_validity, sizeof(uid_validity), TRUE); + + /* set next-uid */ + if (hdr->next_uid != 0) + next_uid = hdr->next_uid; + else if (backup_hdr != NULL && backup_hdr->next_uid != 0) + next_uid = backup_hdr->next_uid; + else + next_uid = dbox_get_uidvalidity_next(ctx->box->list); + mail_index_update_header(ctx->trans, + offsetof(struct mail_index_header, next_uid), + &next_uid, sizeof(next_uid), TRUE); + + /* set highest-modseq */ + mail_index_update_highest_modseq(ctx->trans, + mail_index_modseq_get_highest(ctx->view)); + if (ctx->backup_view != NULL) { + mail_index_update_highest_modseq(ctx->trans, + mail_index_modseq_get_highest(ctx->backup_view)); + + } +} + struct dbox_sync_rebuild_context * dbox_sync_index_rebuild_init(struct mailbox *box, struct mail_index_view *view, @@ -123,6 +170,7 @@ void dbox_sync_index_rebuild_deinit(struct dbox_sync_rebuild_context **_ctx) struct dbox_sync_rebuild_context *ctx = *_ctx; *_ctx = NULL; + dbox_sync_rebuild_header(ctx); if (ctx->backup_index != NULL) { mail_index_view_close(&ctx->backup_view); mail_index_close(ctx->backup_index); 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 51c4f68f1d..20721ac990 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage-rebuild.c @@ -392,6 +392,49 @@ rebuild_mailbox_multi(struct mdbox_storage_rebuild_context *ctx, } } +static void +mdbox_rebuild_get_header(struct mail_index_view *view, uint32_t hdr_ext_id, + struct mdbox_index_header *hdr_r) +{ + const void *data; + size_t data_size; + + mail_index_get_header_ext(view, hdr_ext_id, &data, &data_size); + memset(hdr_r, 0, sizeof(*hdr_r)); + memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); +} + +static void mdbox_header_update(struct dbox_sync_rebuild_context *rebuild_ctx, + struct mdbox_mailbox *mbox) +{ + struct mdbox_index_header hdr, backup_hdr; + + mdbox_rebuild_get_header(rebuild_ctx->view, mbox->hdr_ext_id, &hdr); + if (rebuild_ctx->backup_view == NULL) + memset(&backup_hdr, 0, sizeof(backup_hdr)); + else { + mdbox_rebuild_get_header(rebuild_ctx->backup_view, + mbox->hdr_ext_id, &backup_hdr); + } + + /* make sure we have valid mailbox guid */ + if (mail_guid_128_is_empty(hdr.mailbox_guid)) { + if (!mail_guid_128_is_empty(backup_hdr.mailbox_guid)) { + memcpy(hdr.mailbox_guid, backup_hdr.mailbox_guid, + sizeof(hdr.mailbox_guid)); + } else { + mail_generate_guid_128(hdr.mailbox_guid); + } + } + + /* update map's uid-validity */ + hdr.map_uid_validity = dbox_map_get_uid_validity(mbox->storage->map); + + /* and write changes */ + mail_index_update_header_ext(rebuild_ctx->trans, mbox->hdr_ext_id, 0, + &hdr, sizeof(hdr)); +} + static int rebuild_mailbox(struct mdbox_storage_rebuild_context *ctx, struct mail_namespace *ns, const char *name) @@ -429,6 +472,7 @@ rebuild_mailbox(struct mdbox_storage_rebuild_context *ctx, } rebuild_ctx = dbox_sync_index_rebuild_init(&mbox->box, view, trans); + mdbox_header_update(rebuild_ctx, mbox); rebuild_mailbox_multi(ctx, rebuild_ctx, mbox, view, trans); dbox_sync_index_rebuild_deinit(&rebuild_ctx);