dovecot-2.2: dsync: Fixed handling UID renumbering when new mail...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jan 9 05:43:21 EET 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/a0493fa018fa
changeset: 15612:a0493fa018fa
user: Timo Sirainen <tss at iki.fi>
date: Wed Jan 09 05:43:09 2013 +0200
description:
dsync: Fixed handling UID renumbering when new mail was saved during dsync.
diffstat:
src/doveadm/dsync/dsync-mailbox-import.c | 65 ++++++++++++++++++++++---------
1 files changed, 46 insertions(+), 19 deletions(-)
diffs (92 lines):
diff -r cc77431b09b4 -r a0493fa018fa src/doveadm/dsync/dsync-mailbox-import.c
--- a/src/doveadm/dsync/dsync-mailbox-import.c Wed Jan 09 05:42:03 2013 +0200
+++ b/src/doveadm/dsync/dsync-mailbox-import.c Wed Jan 09 05:43:09 2013 +0200
@@ -1393,11 +1393,28 @@
{
struct seq_range_iter iter;
const uint32_t *wanted_uids;
- uint32_t saved_uid, highest_unwanted_uid = 0;
+ uint32_t saved_uid, highest_wanted_uid = 0;
uint32_t seq1, seq2, lowest_saved_uid = (uint32_t)-1;
+ uint32_t lowest_unwanted_uid = (uint32_t)-1;
unsigned int i, n, wanted_count;
int ret = 0;
+ /* wanted_uids contains the UIDs we tried to save mails with.
+ if nothing changed during dsync, we should have the expected UIDs
+ (changes->saved_uids) and all is well.
+
+ if any new messages got inserted during dsync, we'll need to fix up
+ the UIDs and let the next dsync fix up the other side. for example:
+
+ remote uids = 5,7,9 = wanted_uids
+ remote uidnext = 12
+ locally added new uid=5 ->
+ saved_uids = 10,7,9
+
+ we'll now need to reassign UIDs 5 and 10. or more generally, we
+ need to reassign UIDs [original local uidnext .. lowest saved_uid-1]
+ and [lowest unwanted uid .. remote uidnext-1] */
+
/* find the highest wanted UID that doesn't match what we got */
wanted_uids = array_get(&importer->wanted_uids, &wanted_count);
seq_range_array_iter_init(&iter, &changes->saved_uids); i = n = 0;
@@ -1405,30 +1422,40 @@
i_assert(i < wanted_count);
if (lowest_saved_uid > saved_uid)
lowest_saved_uid = saved_uid;
- if (saved_uid != wanted_uids[i]) {
- if (highest_unwanted_uid < wanted_uids[i])
- highest_unwanted_uid = wanted_uids[i];
+ if (saved_uid == wanted_uids[i]) {
+ if (highest_wanted_uid < saved_uid)
+ highest_wanted_uid = saved_uid;
+ } else {
+ if (lowest_unwanted_uid > saved_uid)
+ lowest_unwanted_uid = saved_uid;
}
i++;
}
+ i_assert(lowest_unwanted_uid == (uint32_t)-1 ||
+ lowest_unwanted_uid == highest_wanted_uid+1 ||
+ highest_wanted_uid == 0);
- if (highest_unwanted_uid == 0 && i > 0 &&
- importer->local_uid_next <= lowest_saved_uid-1) {
- /* we didn't see any unwanted UIDs, but we'll still need to
- verify that messages didn't just get saved locally to a gap
- that we left in local_uid_next..(lowest_saved_uid-1) */
- highest_unwanted_uid = lowest_saved_uid-1;
+ if (importer->local_uid_next != lowest_saved_uid &&
+ lowest_saved_uid != (uint32_t)-1) {
+ /* [original local uidnext .. lowest saved_uid-1] */
+ mailbox_get_seq_range(importer->box, importer->local_uid_next,
+ lowest_saved_uid-1, &seq1, &seq2);
+ if (seq1 > 0) {
+ ret = reassign_uids_in_seq_range(importer->box,
+ seq1, seq2);
+ *changes_during_sync_r = TRUE;
+ }
}
- if (highest_unwanted_uid == 0)
- seq1 = seq2 = 0;
- else {
- mailbox_get_seq_range(importer->box, importer->local_uid_next,
- highest_unwanted_uid, &seq1, &seq2);
- }
- if (seq1 > 0) {
- ret = reassign_uids_in_seq_range(importer->box, seq1, seq2);
- *changes_during_sync_r = TRUE;
+ if (lowest_unwanted_uid < importer->remote_uid_next) {
+ /* [highest wanted_uid+1 .. remote uidnext-1] */
+ mailbox_get_seq_range(importer->box, lowest_unwanted_uid,
+ importer->remote_uid_next-1, &seq1, &seq2);
+ if (seq1 > 0) {
+ ret = reassign_uids_in_seq_range(importer->box,
+ seq1, seq2);
+ *changes_during_sync_r = TRUE;
+ }
}
return ret;
}
More information about the dovecot-cvs
mailing list