dovecot: If MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES is set, check i...

dovecot at dovecot.org dovecot at dovecot.org
Thu Nov 15 15:01:33 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/a4c87d5d881c
changeset: 6810:a4c87d5d881c
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Nov 15 15:01:27 2007 +0200
description:
If MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES is set, check if there's anything to
sync before locking transaction log.

diffstat:

1 file changed, 64 insertions(+), 30 deletions(-)
src/lib-index/mail-index-sync.c |   94 ++++++++++++++++++++++++++-------------

diffs (140 lines):

diff -r 9d8c00d4c467 -r a4c87d5d881c src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Thu Nov 15 14:45:27 2007 +0200
+++ b/src/lib-index/mail-index-sync.c	Thu Nov 15 15:01:27 2007 +0200
@@ -252,11 +252,10 @@ mail_index_sync_read_and_sort(struct mai
 }
 
 static bool
-mail_index_need_sync(struct mail_index *index,
-		     const struct mail_index_header *hdr,
-		     enum mail_index_sync_flags flags,
+mail_index_need_sync(struct mail_index *index, enum mail_index_sync_flags flags,
 		     uint32_t log_file_seq, uoff_t log_file_offset)
 {
+	const struct mail_index_header *hdr = &index->map->hdr;
 	if ((flags & MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES) == 0)
 		return TRUE;
 
@@ -323,28 +322,25 @@ int mail_index_sync_begin(struct mail_in
 	return ret;
 }
 
-int mail_index_sync_begin_to(struct mail_index *index,
-			     struct mail_index_sync_ctx **ctx_r,
-			     struct mail_index_view **view_r,
-			     struct mail_index_transaction **trans_r,
-			     uint32_t log_file_seq, uoff_t log_file_offset,
-			     enum mail_index_sync_flags flags)
+static int
+mail_index_sync_begin_init(struct mail_index *index,
+			   enum mail_index_sync_flags flags,
+			   uint32_t log_file_seq, uoff_t log_file_offset)
 {
 	const struct mail_index_header *hdr;
-	struct mail_index_sync_ctx *ctx;
-	struct mail_index_view *sync_view;
-	enum mail_index_transaction_flags trans_flags;
 	uint32_t seq;
 	uoff_t offset;
+	bool locked = FALSE;
 	int ret;
 
-	i_assert(!index->syncing);
-
-	if (log_file_seq != (uint32_t)-1)
-		flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
-
-	if (mail_transaction_log_sync_lock(index->log, &seq, &offset) < 0)
-		return -1;
+	/* if we require changes, don't lock transaction log yet. first check
+	   if there's anything to sync. */
+	if ((flags & MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES) == 0) {
+		if (mail_transaction_log_sync_lock(index->log,
+						   &seq, &offset) < 0)
+			return -1;
+		locked = TRUE;
+	}
 
 	/* The view must contain what we expect the mailbox to look like
 	   currently. That allows the backend to update external flag
@@ -355,24 +351,35 @@ int mail_index_sync_begin_to(struct mail
 	   mail_index_sync_commit(). */
 	if ((ret = mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD)) <= 0) {
 		if (ret == 0) {
-			mail_transaction_log_sync_unlock(index->log);
+			if (locked)
+				mail_transaction_log_sync_unlock(index->log);
 			return -1;
 		}
 
 		/* let's try again */
 		if (mail_index_map(index, MAIL_INDEX_SYNC_HANDLER_HEAD) <= 0) {
+			if (locked)
+				mail_transaction_log_sync_unlock(index->log);
+			return -1;
+		}
+	}
+
+	if (!mail_index_need_sync(index, flags,
+				  log_file_seq, log_file_offset)) {
+		if (locked)
 			mail_transaction_log_sync_unlock(index->log);
-			return -1;
-		}
-	}
+		return 0;
+	}
+
+	if (!locked) {
+		/* it looks like we have something to sync. lock the file and
+		   check again. */
+		flags &= ~MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
+		return mail_index_sync_begin_init(index, flags, log_file_seq,
+						  log_file_offset);
+	}
+
 	hdr = &index->map->hdr;
-
-	if (!mail_index_need_sync(index, hdr, flags,
-				  log_file_seq, log_file_offset)) {
-		mail_transaction_log_sync_unlock(index->log);
-		return 0;
-	}
-
 	if (hdr->log_file_tail_offset > hdr->log_file_head_offset ||
 	    hdr->log_file_seq > seq ||
 	    (hdr->log_file_seq == seq && hdr->log_file_tail_offset > offset)) {
@@ -382,6 +389,33 @@ int mail_index_sync_begin_to(struct mail
 			index->filepath);
 		mail_index_fsck_locked(index);
 	}
+	return 1;
+}
+
+int mail_index_sync_begin_to(struct mail_index *index,
+			     struct mail_index_sync_ctx **ctx_r,
+			     struct mail_index_view **view_r,
+			     struct mail_index_transaction **trans_r,
+			     uint32_t log_file_seq, uoff_t log_file_offset,
+			     enum mail_index_sync_flags flags)
+{
+	const struct mail_index_header *hdr;
+	struct mail_index_sync_ctx *ctx;
+	struct mail_index_view *sync_view;
+	enum mail_index_transaction_flags trans_flags;
+	int ret;
+
+	i_assert(!index->syncing);
+
+	if (log_file_seq != (uint32_t)-1)
+		flags |= MAIL_INDEX_SYNC_FLAG_REQUIRE_CHANGES;
+
+	ret = mail_index_sync_begin_init(index, flags, log_file_seq,
+					 log_file_offset);
+	if (ret <= 0)
+		return ret;
+
+	hdr = &index->map->hdr;
 
 	ctx = i_new(struct mail_index_sync_ctx, 1);
 	ctx->index = index;


More information about the dovecot-cvs mailing list