dovecot: Handle UIDVALIDITY changes by resetting index.
dovecot at dovecot.org
dovecot at dovecot.org
Sun Jul 1 01:05:51 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/f8caf3c6a5a7
changeset: 5850:f8caf3c6a5a7
user: Timo Sirainen <tss at iki.fi>
date: Sun Jul 01 01:05:40 2007 +0300
description:
Handle UIDVALIDITY changes by resetting index.
diffstat:
3 files changed, 54 insertions(+), 22 deletions(-)
src/lib-storage/index/maildir/maildir-sync.c | 17 ++++---
src/lib-storage/index/mbox/mbox-sync-private.h | 3 +
src/lib-storage/index/mbox/mbox-sync.c | 56 +++++++++++++++++-------
diffs (183 lines):
diff -r a9df50952600 -r f8caf3c6a5a7 src/lib-storage/index/maildir/maildir-sync.c
--- 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 @@ int maildir_sync_index(struct maildir_in
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 @@ int maildir_sync_index(struct maildir_in
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);
-
- mail_index_mark_corrupted(mbox->ibox.index);
- return -1;
+ i_warning("Maildir %s: UIDVALIDITY changed (%u -> %u)",
+ mbox->path, hdr->uid_validity, uid_validity);
+ mail_index_reset(trans);
+
+ memset(&empty_hdr, 0, sizeof(empty_hdr));
+ empty_hdr.next_uid = 1;
+ hdr = &empty_hdr;
}
seq = prev_uid = 0;
@@ -1293,6 +1295,7 @@ int maildir_sync_index(struct maildir_in
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 @@ int maildir_sync_index(struct maildir_in
}
}
- 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;
diff -r a9df50952600 -r f8caf3c6a5a7 src/lib-storage/index/mbox/mbox-sync-private.h
--- 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 mbox_sync_context {
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 @@ struct mbox_sync_context {
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);
diff -r a9df50952600 -r f8caf3c6a5a7 src/lib-storage/index/mbox/mbox-sync.c
--- 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 @@ static int mbox_sync_read_index_syncs(st
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;
}
@@ -324,6 +324,11 @@ mbox_sync_read_index_rec(struct mbox_syn
const struct mail_index_record *rec = NULL;
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);
@@ -376,6 +381,11 @@ static int mbox_sync_find_index_md5(stru
uint32_t messages_count;
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);
@@ -1001,6 +1011,8 @@ mbox_sync_seek_to_uid(struct mbox_sync_c
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);
@@ -1037,6 +1049,8 @@ static int mbox_sync_partial_seek_next(s
{
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 */
@@ -1077,6 +1091,21 @@ static int mbox_sync_partial_seek_next(s
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 @@ static int mbox_sync_loop(struct mbox_sy
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 @@ static void mbox_sync_restart(struct mbo
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;
More information about the dovecot-cvs
mailing list