dovecot: Handle next_uid changes better.
dovecot at dovecot.org
dovecot at dovecot.org
Mon Jul 9 05:44:46 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/6ac8d6c93d34
changeset: 5932:6ac8d6c93d34
user: Timo Sirainen <tss at iki.fi>
date: Mon Jul 09 04:40:54 2007 +0300
description:
Handle next_uid changes better.
diffstat:
3 files changed, 37 insertions(+), 40 deletions(-)
src/lib-storage/index/maildir/maildir-sync-index.c | 53 ++++++++------------
src/lib-storage/index/maildir/maildir-uidlist.c | 20 ++++---
src/lib-storage/index/maildir/maildir-uidlist.h | 4 +
diffs (156 lines):
diff -r 6371b2a7178f -r 6ac8d6c93d34 src/lib-storage/index/maildir/maildir-sync-index.c
--- a/src/lib-storage/index/maildir/maildir-sync-index.c Mon Jul 09 04:31:46 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-sync-index.c Mon Jul 09 04:40:54 2007 +0300
@@ -248,7 +248,7 @@ int maildir_sync_index(struct maildir_in
enum maildir_uidlist_rec_flag uflags;
const char *filename;
ARRAY_TYPE(keyword_indexes) idx_keywords;
- uint32_t uid_validity, next_uid;
+ uint32_t uid_validity, next_uid, hdr_next_uid;
unsigned int changes = 0;
int ret = 0;
bool expunged, full_rescan = FALSE;
@@ -260,16 +260,19 @@ int maildir_sync_index(struct maildir_in
uid_validity = maildir_uidlist_get_uid_validity(mbox->uidlist);
if (uid_validity != hdr->uid_validity &&
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 */
+ /* uidvalidity changed and index isn't being synced for the
+ first time, reset the index so we can add all messages as
+ new */
i_warning("Maildir %s: UIDVALIDITY changed (%u -> %u)",
mbox->path, hdr->uid_validity, uid_validity);
mail_index_reset(trans);
+ maildir_uidlist_set_next_uid(mbox->uidlist, 1, TRUE);
memset(&empty_hdr, 0, sizeof(empty_hdr));
empty_hdr.next_uid = 1;
hdr = &empty_hdr;
}
+ hdr_next_uid = hdr->next_uid;
mbox->syncing_commit = TRUE;
seq = prev_uid = 0;
@@ -299,13 +302,14 @@ int maildir_sync_index(struct maildir_in
ctx->uid = uid;
if (seq > hdr->messages_count) {
- if (uid < hdr->next_uid) {
+ if (uid < hdr_next_uid) {
maildir_handle_uid_insertion(ctx, uflags,
filename, uid);
seq--;
continue;
}
+ hdr_next_uid = uid + 1;
mail_index_append(trans, uid, &seq);
mail_index_update_flags(trans, seq, MODIFY_REPLACE,
ctx->flags);
@@ -440,43 +444,30 @@ int maildir_sync_index(struct maildir_in
/* expunge the rest */
for (seq++; seq <= hdr->messages_count; seq++)
mail_index_expunge(trans, seq);
-
- /* next_uid must be updated only in non-partial syncs since
- partial syncs don't add the new mails to index. also we'll
- 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),
- &next_uid, sizeof(next_uid), FALSE);
- }
}
if (ctx->changed)
mbox->maildir_hdr.cur_mtime = time(NULL);
maildir_index_update_ext_header(mbox, trans);
- if (hdr->uid_validity == 0) {
- /* get the initial uidvalidity */
- uid_validity = maildir_uidlist_get_uid_validity(mbox->uidlist);
- if (uid_validity == 0) {
- uid_validity = ioloop_time;
- maildir_uidlist_set_uid_validity(mbox->uidlist,
- uid_validity, 0);
- }
- } else if (uid_validity == 0) {
- maildir_uidlist_set_uid_validity(mbox->uidlist,
- hdr->uid_validity,
- hdr->next_uid);
- }
-
- if (uid_validity != hdr->uid_validity && uid_validity != 0) {
+ if (uid_validity == 0) {
+ uid_validity = hdr->uid_validity != 0 ?
+ hdr->uid_validity : ioloop_time;
+ maildir_uidlist_set_uid_validity(mbox->uidlist, uid_validity);
+ }
+ maildir_uidlist_set_next_uid(mbox->uidlist, hdr_next_uid, FALSE);
+
+ if (uid_validity != hdr->uid_validity) {
mail_index_update_header(trans,
offsetof(struct mail_index_header, uid_validity),
&uid_validity, sizeof(uid_validity), TRUE);
}
+ next_uid = maildir_uidlist_get_next_uid(mbox->uidlist);
+ if (hdr_next_uid < next_uid) {
+ mail_index_update_header(trans,
+ offsetof(struct mail_index_header, next_uid),
+ &next_uid, sizeof(next_uid), FALSE);
+ }
return ret < 0 ? -1 : (full_rescan ? 0 : 1);
}
diff -r 6371b2a7178f -r 6ac8d6c93d34 src/lib-storage/index/maildir/maildir-uidlist.c
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Mon Jul 09 04:31:46 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c Mon Jul 09 04:40:54 2007 +0300
@@ -543,18 +543,22 @@ uint32_t maildir_uidlist_get_uid_validit
return uidlist->uid_validity;
}
+uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist)
+{
+ return !uidlist->initial_read ? 0 : uidlist->next_uid;
+}
+
void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist,
- uint32_t uid_validity, uint32_t next_uid)
+ uint32_t uid_validity)
{
uidlist->uid_validity = uid_validity;
- /* set next_uid only if we know newer UIDs haven't been added yet */
- if (uidlist->next_uid < next_uid)
+}
+
+void maildir_uidlist_set_next_uid(struct maildir_uidlist *uidlist,
+ uint32_t next_uid, bool force)
+{
+ if (uidlist->next_uid < next_uid || force)
uidlist->next_uid = next_uid;
-}
-
-uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist)
-{
- return !uidlist->initial_read ? 0 : uidlist->next_uid;
}
static int maildir_uidlist_rewrite_fd(struct maildir_uidlist *uidlist, int fd,
diff -r 6371b2a7178f -r 6ac8d6c93d34 src/lib-storage/index/maildir/maildir-uidlist.h
--- a/src/lib-storage/index/maildir/maildir-uidlist.h Mon Jul 09 04:31:46 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.h Mon Jul 09 04:40:54 2007 +0300
@@ -42,7 +42,9 @@ uint32_t maildir_uidlist_get_next_uid(st
uint32_t maildir_uidlist_get_next_uid(struct maildir_uidlist *uidlist);
void maildir_uidlist_set_uid_validity(struct maildir_uidlist *uidlist,
- uint32_t uid_validity, uint32_t next_uid);
+ uint32_t uid_validity);
+void maildir_uidlist_set_next_uid(struct maildir_uidlist *uidlist,
+ uint32_t next_uid, bool force);
/* Sync uidlist with what's actually on maildir. Returns same as
maildir_uidlist_lock(). */
More information about the dovecot-cvs
mailing list