dovecot-2.1: imapc: Fixed detecting when messages are missing fr...

dovecot at dovecot.org dovecot at dovecot.org
Sun Oct 9 17:07:28 EEST 2011


details:   http://hg.dovecot.org/dovecot-2.1/rev/305ca9c93dd7
changeset: 13622:305ca9c93dd7
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Oct 09 17:15:31 2011 +0300
description:
imapc: Fixed detecting when messages are missing from index.

diffstat:

 src/lib-storage/index/imapc/imapc-mail.c    |   8 +---
 src/lib-storage/index/imapc/imapc-mailbox.c |  13 +------
 src/lib-storage/index/imapc/imapc-storage.c |  51 +++++++++++++++-------------
 src/lib-storage/index/imapc/imapc-storage.h |   5 +-
 src/lib-storage/index/imapc/imapc-sync.c    |  36 +++++++++++++++----
 5 files changed, 61 insertions(+), 52 deletions(-)

diffs (210 lines):

diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-mail.c
--- a/src/lib-storage/index/imapc/imapc-mail.c	Sun Oct 09 16:41:17 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mail.c	Sun Oct 09 17:15:31 2011 +0300
@@ -30,8 +30,6 @@
 {
 	struct imapc_mailbox *mbox = (struct imapc_mailbox *)_mail->box;
 	struct imapc_msgmap *msgmap;
-	struct imapc_command *cmd;
-	struct imapc_simple_context sctx;
 	uint32_t lseq, rseq;
 
 	if (mbox->sync_view != NULL) {
@@ -47,11 +45,7 @@
 
 	/* we may be running against a server that hasn't bothered sending
 	   us an EXPUNGE. see if NOOP sends it. */
-	imapc_simple_context_init(&sctx, mbox->storage);
-	cmd = imapc_client_mailbox_cmd(mbox->client_box,
-				       imapc_simple_callback, &sctx);
-	imapc_command_send(cmd, "NOOP");
-	imapc_simple_run(&sctx);
+	imapc_mailbox_noop(mbox);
 
 	return !imapc_msgmap_uid_to_rseq(msgmap, _mail->uid, &rseq);
 }
diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-mailbox.c
--- a/src/lib-storage/index/imapc/imapc-mailbox.c	Sun Oct 09 16:41:17 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-mailbox.c	Sun Oct 09 17:15:31 2011 +0300
@@ -12,8 +12,8 @@
 
 #define NOTIFY_DELAY_MSECS 500
 
-static void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
-					const char *reason, ...)
+void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
+				 const char *reason, ...)
 {
 	va_list va;
 
@@ -239,15 +239,6 @@
 		imapc_msgmap_append(msgmap, rseq, uid);
 		if (uid < mbox->min_append_uid) {
 			/* message is already added to index */
-			if (!mbox->initial_sync_done &&
-			    !mail_index_lookup_seq(mbox->delayed_sync_view,
-						   uid, lseq_r)) {
-				imapc_mailbox_set_corrupted(mbox,
-					"Expunged message reappeared "
-					"(uid=%u < next_uid=%u)",
-					uid, mbox->min_append_uid);
-				return -1;
-			}
 		} else if (mbox->syncing) {
 			mail_index_append(mbox->delayed_sync_trans,
 					  uid, lseq_r);
diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-storage.c
--- a/src/lib-storage/index/imapc/imapc-storage.c	Sun Oct 09 16:41:17 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.c	Sun Oct 09 17:15:31 2011 +0300
@@ -137,31 +137,16 @@
 	imapc_client_stop(ctx->storage->client);
 }
 
-static void imapc_noop_callback(const struct imapc_command_reply *reply,
-				void *context)
+void imapc_mailbox_noop(struct imapc_mailbox *mbox)
+{
+	struct imapc_command *cmd;
+	struct imapc_simple_context sctx;
 
-{
-	struct imapc_storage *storage = context;
-
-	if (reply->state == IMAPC_COMMAND_STATE_OK)
-		;
-	else if (reply->state == IMAPC_COMMAND_STATE_NO)
-		imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply);
-	else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED)
-		mail_storage_set_internal_error(&storage->storage);
-	else {
-		mail_storage_set_critical(&storage->storage,
-			"imapc: NOOP failed: %s", reply->text_full);
-	}
-}
-
-void imapc_noop_stop_callback(const struct imapc_command_reply *reply,
-			       void *context)
-{
-	struct imapc_storage *storage = context;
-
-	imapc_noop_callback(reply, context);
-	imapc_client_stop(storage->client);
+	imapc_simple_context_init(&sctx, mbox->storage);
+	cmd = imapc_client_mailbox_cmd(mbox->client_box,
+				       imapc_simple_callback, &sctx);
+	imapc_command_send(cmd, "NOOP");
+	imapc_simple_run(&sctx);
 }
 
 static void imapc_storage_untagged_cb(const struct imapc_untagged_reply *reply,
@@ -657,6 +642,24 @@
 	return 0;
 }
 
+static void imapc_noop_callback(const struct imapc_command_reply *reply,
+				void *context)
+
+{
+	struct imapc_storage *storage = context;
+
+	if (reply->state == IMAPC_COMMAND_STATE_OK)
+		;
+	else if (reply->state == IMAPC_COMMAND_STATE_NO)
+		imapc_copy_error_from_reply(storage, MAIL_ERROR_PARAMS, reply);
+	else if (reply->state == IMAPC_COMMAND_STATE_DISCONNECTED)
+		mail_storage_set_internal_error(&storage->storage);
+	else {
+		mail_storage_set_critical(&storage->storage,
+			"imapc: NOOP failed: %s", reply->text_full);
+	}
+}
+
 static void imapc_idle_timeout(struct imapc_mailbox *mbox)
 {
 	struct imapc_command *cmd;
diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-storage.h
--- a/src/lib-storage/index/imapc/imapc-storage.h	Sun Oct 09 16:41:17 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-storage.h	Sun Oct 09 17:15:31 2011 +0300
@@ -116,10 +116,11 @@
 void imapc_simple_run(struct imapc_simple_context *sctx);
 void imapc_simple_callback(const struct imapc_command_reply *reply,
 			   void *context);
-void imapc_noop_stop_callback(const struct imapc_command_reply *reply,
-			      void *context);
 int imapc_mailbox_commit_delayed_trans(struct imapc_mailbox *mbox,
 				       bool *changes_r);
+void imapc_mailbox_noop(struct imapc_mailbox *mbox);
+void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
+				 const char *reason, ...);
 
 void imapc_storage_register_untagged(struct imapc_storage *storage,
 				     const char *name,
diff -r 8fdd22504aab -r 305ca9c93dd7 src/lib-storage/index/imapc/imapc-sync.c
--- a/src/lib-storage/index/imapc/imapc-sync.c	Sun Oct 09 16:41:17 2011 +0300
+++ b/src/lib-storage/index/imapc/imapc-sync.c	Sun Oct 09 17:15:31 2011 +0300
@@ -230,6 +230,26 @@
 	}
 }
 
+static void imapc_initial_sync_check(struct imapc_sync_context *ctx)
+{
+	unsigned int idx_count;
+
+	idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view);
+	if (idx_count >= ctx->mbox->exists_count)
+		return;
+
+	/* NOOP should send EXPUNGEs */
+	imapc_mailbox_noop(ctx->mbox);
+
+	idx_count = mail_index_view_get_messages_count(ctx->mbox->delayed_sync_view);
+	if (idx_count < ctx->mbox->exists_count) {
+		imapc_mailbox_set_corrupted(ctx->mbox,
+			"Index is missing messages (%u < %u)",
+			idx_count, ctx->mbox->exists_count);
+		ctx->failed = TRUE;
+	}
+}
+
 static void imapc_sync_index(struct imapc_sync_context *ctx)
 {
 	struct imapc_mailbox *mbox = ctx->mbox;
@@ -292,10 +312,15 @@
 	/* add uidnext after all appends */
 	imapc_sync_uid_next(ctx);
 
-	imapc_sync_expunge_eom(ctx);
+	if (!ctx->failed)
+		imapc_sync_expunge_eom(ctx);
 	if (mbox->box.v.sync_notify != NULL)
 		mbox->box.v.sync_notify(&mbox->box, 0, 0);
-	mbox->initial_sync_done = TRUE;
+
+	if (!mbox->initial_sync_done) {
+		imapc_initial_sync_check(ctx);
+		mbox->initial_sync_done = TRUE;
+	}
 }
 
 static int
@@ -390,7 +415,6 @@
 imapc_mailbox_sync_init(struct mailbox *box, enum mailbox_sync_flags flags)
 {
 	struct imapc_mailbox *mbox = (struct imapc_mailbox *)box;
-	struct imapc_command *cmd;
 	enum imapc_capability capabilities;
 	bool changes;
 	int ret = 0;
@@ -404,11 +428,7 @@
 	if ((capabilities & IMAPC_CAPABILITY_IDLE) == 0) {
 		/* IDLE not supported. do NOOP to get latest changes
 		   before starting sync. */
-		cmd = imapc_client_mailbox_cmd(mbox->client_box,
-					       imapc_noop_stop_callback,
-					       mbox->storage);
-		imapc_command_send(cmd, "NOOP");
-		imapc_storage_run(mbox->storage);
+		imapc_mailbox_noop(mbox);
 	}
 
 	if (imapc_mailbox_commit_delayed_trans(mbox, &changes) < 0)


More information about the dovecot-cvs mailing list