dovecot-1.2: QRESYNC: If MODSEQs were returned in FETCH replies ...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jun 11 14:40:26 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/2d62129a709b
changeset: 7815:2d62129a709b
user: Timo Sirainen <tss at iki.fi>
date: Wed Jun 11 14:39:52 2008 +0300
description:
QRESYNC: If MODSEQs were returned in FETCH replies but there are pending
expunges, send a low enough HIGHESTMODSEQ reply to make sure the client will
later see the expunges.
diffstat:
8 files changed, 44 insertions(+), 12 deletions(-)
src/imap/client.h | 3 +++
src/imap/cmd-select.c | 1 +
src/imap/imap-fetch.c | 1 +
src/imap/imap-sync.c | 33 +++++++++++++++++++++++++--------
src/lib-index/mail-index-view-sync.c | 4 +++-
src/lib-index/mail-index.h | 3 ++-
src/lib-storage/index/index-sync.c | 8 ++++++--
src/lib-storage/mail-storage.h | 3 +++
diffs (205 lines):
diff -r 1ae3d4a5057b -r 2d62129a709b src/imap/client.h
--- a/src/imap/client.h Wed Jun 11 14:37:49 2008 +0300
+++ b/src/imap/client.h Wed Jun 11 14:39:52 2008 +0300
@@ -93,6 +93,8 @@ struct client {
struct client_command_context *command_queue;
unsigned int command_queue_size;
+ uint64_t sync_last_full_modseq;
+
/* SEARCHRES extension: Last saved SEARCH result */
ARRAY_TYPE(seq_range) search_saved_uidset;
/* SEARCH=CONTEXT extension: Searches that get updated */
@@ -113,6 +115,7 @@ struct client {
unsigned int changing_mailbox:1;
unsigned int input_skip_line:1; /* skip all the data until we've
found a new line */
+ unsigned int modseqs_sent_since_sync:1;
};
/* Create new client with specified input/output handles. socket specifies
diff -r 1ae3d4a5057b -r 2d62129a709b src/imap/cmd-select.c
--- a/src/imap/cmd-select.c Wed Jun 11 14:37:49 2008 +0300
+++ b/src/imap/cmd-select.c Wed Jun 11 14:39:52 2008 +0300
@@ -313,6 +313,7 @@ select_open(struct imap_select_context *
client_send_line(client,
t_strdup_printf("* OK [HIGHESTMODSEQ %llu]",
(unsigned long long)status.highest_modseq));
+ client->sync_last_full_modseq = status.highest_modseq;
}
if (ctx->qresync_uid_validity == status.uidvalidity) {
diff -r 1ae3d4a5057b -r 2d62129a709b src/imap/imap-fetch.c
--- a/src/imap/imap-fetch.c Wed Jun 11 14:37:49 2008 +0300
+++ b/src/imap/imap-fetch.c Wed Jun 11 14:39:52 2008 +0300
@@ -752,6 +752,7 @@ fetch_modseq_init(struct imap_fetch_cont
client_enable(ctx->client, MAILBOX_FEATURE_CONDSTORE);
imap_fetch_add_handler(ctx, TRUE, FALSE, name, NULL,
fetch_modseq, NULL);
+ ctx->client->modseqs_sent_since_sync = TRUE;
return TRUE;
}
diff -r 1ae3d4a5057b -r 2d62129a709b src/imap/imap-sync.c
--- a/src/imap/imap-sync.c Wed Jun 11 14:37:49 2008 +0300
+++ b/src/imap/imap-sync.c Wed Jun 11 14:39:52 2008 +0300
@@ -160,6 +160,7 @@ imap_sync_init(struct client *client, st
int imap_sync_deinit(struct imap_sync_context *ctx)
{
+ struct client *client = ctx->client;
struct mailbox_status status;
int ret;
@@ -168,7 +169,8 @@ int imap_sync_deinit(struct imap_sync_co
array_free(&ctx->expunges);
if (mailbox_sync_deinit(&ctx->sync_ctx, STATUS_UIDVALIDITY |
- STATUS_MESSAGES | STATUS_RECENT, &status) < 0 ||
+ STATUS_MESSAGES | STATUS_RECENT |
+ STATUS_HIGHESTMODSEQ, &status) < 0 ||
ctx->failed) {
mailbox_transaction_rollback(&ctx->t);
array_free(&ctx->tmp_keywords);
@@ -176,25 +178,38 @@ int imap_sync_deinit(struct imap_sync_co
return -1;
}
+ if (!status.sync_delayed_expunges || status.highest_modseq == 0)
+ client->sync_last_full_modseq = status.highest_modseq;
+ else if (client->modseqs_sent_since_sync &&
+ (client->enabled_features & MAILBOX_FEATURE_QRESYNC) != 0) {
+ /* if client updates highest-modseq using returned MODSEQs
+ it loses expunges. try to avoid this by sending it a lower
+ pre-expunge HIGHESTMODSEQ reply. */
+ client_send_line(client, t_strdup_printf(
+ "* OK [HIGHESTMODSEQ %llu]",
+ (unsigned long long)client->sync_last_full_modseq));
+ }
+ client->modseqs_sent_since_sync = FALSE;
+
ret = mailbox_transaction_commit(&ctx->t);
- if (status.uidvalidity != ctx->client->uidvalidity) {
+ if (status.uidvalidity != client->uidvalidity) {
/* most clients would get confused by this. disconnect them. */
- client_disconnect_with_error(ctx->client,
+ client_disconnect_with_error(client,
"Mailbox UIDVALIDITY changed");
}
if (!ctx->no_newmail) {
if (status.messages < ctx->messages_count)
i_panic("Message count decreased");
- ctx->client->messages_count = status.messages;
+ client->messages_count = status.messages;
if (status.messages != ctx->messages_count) {
- client_send_line(ctx->client,
+ client_send_line(client,
t_strdup_printf("* %u EXISTS", status.messages));
}
- if (status.recent != ctx->client->recent_count &&
+ if (status.recent != client->recent_count &&
!ctx->no_newmail) {
- ctx->client->recent_count = status.recent;
- client_send_line(ctx->client,
+ client->recent_count = status.recent;
+ client_send_line(client,
t_strdup_printf("* %u RECENT", status.recent));
}
}
@@ -231,6 +246,7 @@ static int imap_sync_send_flags(struct i
str_printfa(str, "UID %u ", ctx->mail->uid);
if ((mailbox_get_enabled_features(ctx->box) &
MAILBOX_FEATURE_CONDSTORE) != 0) {
+ ctx->client->modseqs_sent_since_sync = TRUE;
str_printfa(str, "MODSEQ %llu ",
(unsigned long long)mail_get_modseq(ctx->mail));
}
@@ -250,6 +266,7 @@ static int imap_sync_send_modseq(struct
str_printfa(str, "UID %u ", ctx->mail->uid);
str_printfa(str, "MODSEQ %llu)",
(unsigned long long)mail_get_modseq(ctx->mail));
+ ctx->client->modseqs_sent_since_sync = TRUE;
return client_send_line(ctx->client, str_c(str));
}
diff -r 1ae3d4a5057b -r 2d62129a709b src/lib-index/mail-index-view-sync.c
--- a/src/lib-index/mail-index-view-sync.c Wed Jun 11 14:37:49 2008 +0300
+++ b/src/lib-index/mail-index-view-sync.c Wed Jun 11 14:39:52 2008 +0300
@@ -633,7 +633,8 @@ mail_index_view_sync_clean_log_syncs(str
array_delete(&view->syncs_hidden, 0, i);
}
-int mail_index_view_sync_commit(struct mail_index_view_sync_ctx **_ctx)
+int mail_index_view_sync_commit(struct mail_index_view_sync_ctx **_ctx,
+ bool *delayed_expunges_r)
{
struct mail_index_view_sync_ctx *ctx = *_ctx;
struct mail_index_view *view = ctx->view;
@@ -642,6 +643,7 @@ int mail_index_view_sync_commit(struct m
i_assert(view->syncing);
*_ctx = NULL;
+ *delayed_expunges_r = ctx->skipped_expunges;
if ((!ctx->last_read || view->inconsistent) &&
(ctx->flags & MAIL_INDEX_VIEW_SYNC_FLAG_FIX_INCONSISTENT) == 0) {
diff -r 1ae3d4a5057b -r 2d62129a709b src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h Wed Jun 11 14:37:49 2008 +0300
+++ b/src/lib-index/mail-index.h Wed Jun 11 14:39:52 2008 +0300
@@ -314,7 +314,8 @@ void
void
mail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
const ARRAY_TYPE(seq_range) **expunges_r);
-int mail_index_view_sync_commit(struct mail_index_view_sync_ctx **ctx);
+int mail_index_view_sync_commit(struct mail_index_view_sync_ctx **ctx,
+ bool *delayed_expunges_r);
/* Returns the index header. */
const struct mail_index_header *
diff -r 1ae3d4a5057b -r 2d62129a709b src/lib-storage/index/index-sync.c
--- a/src/lib-storage/index/index-sync.c Wed Jun 11 14:37:49 2008 +0300
+++ b/src/lib-storage/index/index-sync.c Wed Jun 11 14:39:52 2008 +0300
@@ -325,6 +325,7 @@ int index_mailbox_sync_deinit(struct mai
struct mailbox_sync_rec sync_rec;
const struct mail_index_header *hdr;
uint32_t seq1, seq2;
+ bool delayed_expunges = FALSE;
int ret = ctx->failed ? -1 : 0;
/* finish handling expunges, so we don't break when updating
@@ -332,7 +333,8 @@ int index_mailbox_sync_deinit(struct mai
while (index_mailbox_sync_next_expunge(ctx, &sync_rec) > 0) ;
if (ctx->sync_ctx != NULL) {
- if (mail_index_view_sync_commit(&ctx->sync_ctx) < 0) {
+ if (mail_index_view_sync_commit(&ctx->sync_ctx,
+ &delayed_expunges) < 0) {
mail_storage_set_index_error(ibox);
ret = -1;
}
@@ -354,8 +356,10 @@ int index_mailbox_sync_deinit(struct mai
}
}
- if (ret == 0 && status_items != 0)
+ if (ret == 0 && status_items != 0) {
mailbox_get_status(_ctx->box, status_items, status_r);
+ status_r->sync_delayed_expunges = delayed_expunges;
+ }
index_sync_search_results_update(ctx);
diff -r 1ae3d4a5057b -r 2d62129a709b src/lib-storage/mail-storage.h
--- a/src/lib-storage/mail-storage.h Wed Jun 11 14:37:49 2008 +0300
+++ b/src/lib-storage/mail-storage.h Wed Jun 11 14:39:52 2008 +0300
@@ -189,6 +189,9 @@ struct mailbox_status {
uint64_t highest_modseq;
const ARRAY_TYPE(keywords) *keywords;
+
+ /* There are expunges that haven't been synced yet */
+ unsigned int sync_delayed_expunges:1;
};
struct mailbox_sync_rec {
More information about the dovecot-cvs
mailing list