Mercurial > dovecot > original-hg > dovecot-1.2
changeset 5850:f8caf3c6a5a7 HEAD
Handle UIDVALIDITY changes by resetting index.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sun, 01 Jul 2007 01:05:40 +0300 |
parents | a9df50952600 |
children | fb91e7d729d1 |
files | src/lib-storage/index/maildir/maildir-sync.c src/lib-storage/index/mbox/mbox-sync-private.h src/lib-storage/index/mbox/mbox-sync.c |
diffstat | 3 files changed, 53 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-sync.c Sun Jul 01 01:05:26 2007 +0300 +++ b/src/lib-storage/index/maildir/maildir-sync.c Sun Jul 01 01:05:40 2007 +0300 @@ -1067,6 +1067,7 @@ struct maildir_uidlist_iter_ctx *iter; struct mail_index_transaction *trans = sync_ctx->trans; const struct mail_index_header *hdr; + struct mail_index_header empty_hdr; const struct mail_index_record *rec; uint32_t seq, uid, prev_uid; enum maildir_uidlist_rec_flag uflags; @@ -1087,12 +1088,13 @@ uid_validity != 0 && hdr->uid_validity != 0) { /* uidvalidity changed and mailbox isn't being initialized, reset mailbox so we can add all messages as new */ - mail_storage_set_critical(&mbox->storage->storage, - "Maildir %s sync: UIDVALIDITY changed (%u -> %u)", - mbox->path, hdr->uid_validity, uid_validity); + i_warning("Maildir %s: UIDVALIDITY changed (%u -> %u)", + mbox->path, hdr->uid_validity, uid_validity); + mail_index_reset(trans); - mail_index_mark_corrupted(mbox->ibox.index); - return -1; + memset(&empty_hdr, 0, sizeof(empty_hdr)); + empty_hdr.next_uid = 1; + hdr = &empty_hdr; } seq = prev_uid = 0; @@ -1293,6 +1295,7 @@ have to do it here before syncing index records, since after that the uidlist's next_uid value may have changed. */ next_uid = maildir_uidlist_get_next_uid(mbox->uidlist); + i_assert(next_uid > prev_uid); if (hdr->next_uid < next_uid) { mail_index_update_header(trans, offsetof(struct mail_index_header, next_uid), @@ -1300,7 +1303,7 @@ } } - if (!mbox->syncing_commit) { + if (!mbox->syncing_commit && hdr != &empty_hdr) { /* now, sync the index. NOTE: may recurse back to here with partial syncs */ mbox->syncing_commit = TRUE;
--- a/src/lib-storage/index/mbox/mbox-sync-private.h Sun Jul 01 01:05:26 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync-private.h Sun Jul 01 01:05:40 2007 +0300 @@ -112,6 +112,8 @@ struct mail_index_sync_ctx *index_sync_ctx; struct mail_index_view *sync_view; struct mail_index_transaction *t; + + struct mail_index_header reset_hdr; const struct mail_index_header *hdr; string_t *header, *from_line; @@ -142,6 +144,7 @@ unsigned int renumber_uids:1; unsigned int moved_offsets:1; unsigned int ext_modified:1; + unsigned int index_reset:1; }; int mbox_sync(struct mbox_mailbox *mbox, enum mbox_sync_flags flags);
--- a/src/lib-storage/index/mbox/mbox-sync.c Sun Jul 01 01:05:26 2007 +0300 +++ b/src/lib-storage/index/mbox/mbox-sync.c Sun Jul 01 01:05:40 2007 +0300 @@ -207,7 +207,7 @@ if (sync_ctx->index_sync_ctx == NULL) return 0; - if (uid == 0) { + if (uid == 0 || sync_ctx->index_reset) { /* nothing for this or the future ones */ uid = (uint32_t)-1; } @@ -325,6 +325,11 @@ uint32_t messages_count; int ret = 0; + if (sync_ctx->index_reset) { + *rec_r = NULL; + return 1; + } + messages_count = mail_index_view_get_messages_count(sync_ctx->sync_view); while (sync_ctx->idx_seq <= messages_count) { @@ -377,6 +382,11 @@ const void *data; int ret; + if (sync_ctx->index_reset) { + *rec_r = NULL; + return 0; + } + messages_count = mail_index_view_get_messages_count(sync_ctx->sync_view); while (sync_ctx->idx_seq <= messages_count) { @@ -1001,6 +1011,8 @@ uint32_t seq1, seq2; const struct stat *st; + i_assert(!sync_ctx->index_reset); + if (mail_index_lookup_uid_range(sync_view, uid, (uint32_t)-1, &seq1, &seq2) < 0) { mail_storage_set_index_error(&sync_ctx->mbox->ibox); @@ -1038,6 +1050,8 @@ uint32_t messages_count; int ret; + i_assert(!sync_ctx->index_reset); + /* delete sync records up to next message. so if there's still something left in array, it means the next message needs modifying */ mbox_sync_array_delete_to(&sync_ctx->syncs, next_uid); @@ -1077,6 +1091,21 @@ return ret; } +static bool mbox_sync_uidvalidity_changed(struct mbox_sync_context *sync_ctx) +{ + if (sync_ctx->base_uid_validity != 0 && + sync_ctx->hdr->uid_validity != 0 && + sync_ctx->base_uid_validity != sync_ctx->hdr->uid_validity) { + i_warning("UIDVALIDITY changed (%u -> %u) in mbox file %s", + sync_ctx->hdr->uid_validity, + sync_ctx->base_uid_validity, + sync_ctx->mbox->path); + sync_ctx->index_reset = TRUE; + return TRUE; + } + return FALSE; +} + static int mbox_sync_loop(struct mbox_sync_context *sync_ctx, struct mbox_sync_mail_context *mail_ctx, bool partial) @@ -1108,20 +1137,11 @@ while ((ret = mbox_sync_read_next_mail(sync_ctx, mail_ctx)) > 0) { uid = mail_ctx->mail.uid; - if (mail_ctx->seq == 1 && sync_ctx->base_uid_validity != 0 && - sync_ctx->hdr->uid_validity != 0 && - sync_ctx->base_uid_validity != - sync_ctx->hdr->uid_validity) { - mail_storage_set_critical( - &sync_ctx->mbox->storage->storage, - "UIDVALIDITY changed (%u -> %u) " - "in mbox file %s", - sync_ctx->hdr->uid_validity, - sync_ctx->base_uid_validity, - sync_ctx->mbox->path); - - mail_index_mark_corrupted(sync_ctx->mbox->ibox.index); - return -1; + if (mail_ctx->seq == 1) { + if (mbox_sync_uidvalidity_changed(sync_ctx)) { + sync_ctx->mbox->mbox_sync_dirty = TRUE; + return 0; + } } if (mail_ctx->mail.uid_broken && partial) { @@ -1546,6 +1566,12 @@ mail_index_sync_reset(sync_ctx->index_sync_ctx); mail_index_transaction_reset(sync_ctx->t); + if (sync_ctx->index_reset) { + mail_index_reset(sync_ctx->t); + sync_ctx->reset_hdr.next_uid = 1; + sync_ctx->hdr = &sync_ctx->reset_hdr; + } + sync_ctx->prev_msg_uid = 0; sync_ctx->next_uid = sync_ctx->hdr->next_uid; sync_ctx->idx_next_uid = sync_ctx->hdr->next_uid;