dovecot-2.0-sslstream: Transaction commits can now track how man...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:56:35 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/75d3d4374dda
changeset: 10368:75d3d4374dda
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Nov 18 19:58:07 2009 -0500
description:
Transaction commits can now track how many uid/modseq updates were ignored.

diffstat:

22 files changed, 142 insertions(+), 56 deletions(-)
src/lib-index/mail-cache-transaction.c            |    5 +-
src/lib-index/mail-index-modseq.c                 |    7 ++-
src/lib-index/mail-index-private.h                |    3 +
src/lib-index/mail-index-sync-update.c            |   36 ++++++++++++++++--
src/lib-index/mail-index-sync.c                   |    9 ++++
src/lib-index/mail-index-transaction-private.h    |    2 -
src/lib-index/mail-index-transaction.c            |   42 ++++++++++-----------
src/lib-index/mail-index.h                        |   20 ++++++++--
src/lib-storage/index/cydir/cydir-save.c          |    6 ++-
src/lib-storage/index/cydir/cydir-storage.h       |    3 +
src/lib-storage/index/dbox-multi/mdbox-save.c     |    6 ++-
src/lib-storage/index/dbox-multi/mdbox-storage.h  |    3 +
src/lib-storage/index/dbox-single/sdbox-save.c    |    6 ++-
src/lib-storage/index/dbox-single/sdbox-storage.h |    3 +
src/lib-storage/index/index-storage.h             |    3 +
src/lib-storage/index/index-transaction.c         |   16 ++++----
src/lib-storage/index/maildir/maildir-save.c      |    3 +
src/lib-storage/index/maildir/maildir-storage.h   |    3 +
src/lib-storage/index/mbox/mbox-save.c            |    3 +
src/lib-storage/index/mbox/mbox-storage.h         |    3 +
src/lib-storage/list/index-mailbox-list-sync.c    |    9 +++-
src/lib-storage/mail-storage.h                    |    7 ++-

diffs (truncated from 577 to 300 lines):

diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-cache-transaction.c
--- a/src/lib-index/mail-cache-transaction.c	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-cache-transaction.c	Wed Nov 18 19:58:07 2009 -0500
@@ -68,14 +68,13 @@ static void mail_index_transaction_cache
 
 static int
 mail_index_transaction_cache_commit(struct mail_index_transaction *t,
-				    uint32_t *log_file_seq_r,
-				    uoff_t *log_file_offset_r)
+				    struct mail_index_transaction_commit_result *result_r)
 {
 	struct mail_cache_transaction_ctx *ctx = CACHE_TRANS_CONTEXT(t);
 	struct mail_index_transaction_vfuncs super = ctx->super;
 
 	mail_cache_transaction_commit(&ctx);
-	return super.commit(t, log_file_seq_r, log_file_offset_r);
+	return super.commit(t, result_r);
 }
 
 static void
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index-modseq.c
--- a/src/lib-index/mail-index-modseq.c	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index-modseq.c	Wed Nov 18 19:58:07 2009 -0500
@@ -202,9 +202,12 @@ int mail_index_modseq_set(struct mail_in
 
 	ext = array_idx(&view->map->extensions, ext_map_idx);
 	modseqp = PTR_OFFSET(rec, ext->record_offset);
-	if (*modseqp < min_modseq)
+	if (*modseqp > min_modseq)
+		return 0;
+	else {
 		*modseqp = min_modseq;
-	return 0;
+		return 1;
+	}
 }
 
 static uint64_t
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index-private.h
--- a/src/lib-index/mail-index-private.h	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index-private.h	Wed Nov 18 19:58:07 2009 -0500
@@ -200,6 +200,9 @@ struct mail_index {
 	/* transaction log head seq/offset when we last fscked */
 	uint32_t fsck_log_head_file_seq;
 	uoff_t fsck_log_head_file_offset;
+
+	/* syncing will update this if non-NULL */
+	struct mail_index_transaction_commit_result *sync_commit_result;
 
 	int lock_type, shared_lock_count, excl_lock_count;
 	unsigned int lock_id_counter;
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index-sync-update.c
--- a/src/lib-index/mail-index-sync-update.c	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index-sync-update.c	Wed Nov 18 19:58:07 2009 -0500
@@ -279,9 +279,32 @@ static void *sync_append_record(struct m
 	return ret;
 }
 
+static bool sync_update_ignored_change(struct mail_index_sync_map_ctx *ctx)
+{
+	struct mail_index_transaction_commit_result *result =
+		ctx->view->index->sync_commit_result;
+	uint32_t log_seq;
+	uoff_t log_offset, start_offset;
+
+	if (result == NULL)
+		return FALSE;
+
+	mail_transaction_log_view_get_prev_pos(ctx->view->log_view,
+					       &log_seq, &log_offset);
+	if (log_seq != result->log_file_seq)
+		return FALSE;
+
+	start_offset = result->log_file_offset - result->commit_size;
+	if (log_offset < start_offset || log_offset >= result->log_file_offset)
+		return FALSE;
+
+	return TRUE;
+}
+
 static void sync_uid_update(struct mail_index_sync_map_ctx *ctx,
 			    uint32_t old_uid, uint32_t new_uid)
 {
+	struct mail_index_view *view = ctx->view;
 	struct mail_index_map *map;
 	struct mail_index_record *rec;
 	uint32_t old_seq;
@@ -289,10 +312,12 @@ static void sync_uid_update(struct mail_
 
 	if (new_uid < ctx->view->map->hdr.next_uid) {
 		/* uid update is no longer possible */
+		if (sync_update_ignored_change(ctx))
+			view->index->sync_commit_result->ignored_uid_changes++;
 		return;
 	}
 
-	if (!mail_index_lookup_seq(ctx->view, old_uid, &old_seq))
+	if (!mail_index_lookup_seq(view, old_uid, &old_seq))
 		return;
 
 	map = mail_index_sync_get_atomic_map(ctx);
@@ -320,6 +345,7 @@ sync_modseq_update(struct mail_index_syn
 	const struct mail_transaction_modseq_update *end;
 	uint32_t seq;
 	uint64_t min_modseq, highest_modseq = 0;
+	int ret;
 
 	end = CONST_PTR_OFFSET(u, size);
 	for (; u < end; u++) {
@@ -332,12 +358,16 @@ sync_modseq_update(struct mail_index_syn
 			u->modseq_low32;
 		if (highest_modseq < min_modseq)
 			highest_modseq = min_modseq;
-		if (seq != 0 &&
-		    mail_index_modseq_set(view, seq, min_modseq) < 0) {
+
+		ret = seq == 0 ? 1 :
+			mail_index_modseq_set(view, seq, min_modseq);
+		if (ret < 0) {
 			mail_index_sync_set_corrupted(ctx,
 				"modseqs updated before they were enabled");
 			return -1;
 		}
+		if (ret == 0 && sync_update_ignored_change(ctx))
+			view->index->sync_commit_result->ignored_modseq_changes++;
 	}
 
 	mail_index_modseq_update_highest(ctx->modseq_ctx, highest_modseq);
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index-sync.c
--- a/src/lib-index/mail-index-sync.c	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index-sync.c	Wed Nov 18 19:58:07 2009 -0500
@@ -15,6 +15,7 @@ struct mail_index_sync_ctx {
 	struct mail_index *index;
 	struct mail_index_view *view;
 	struct mail_index_transaction *sync_trans, *ext_trans;
+	struct mail_index_transaction_commit_result *sync_commit_result;
 	enum mail_index_sync_flags flags;
 
 	const struct mail_transaction_header *hdr;
@@ -688,6 +689,12 @@ bool mail_index_sync_have_more(struct ma
 	return FALSE;
 }
 
+void mail_index_sync_set_commit_result(struct mail_index_sync_ctx *ctx,
+				       struct mail_index_transaction_commit_result *result)
+{
+	ctx->sync_commit_result = result;
+}
+
 void mail_index_sync_reset(struct mail_index_sync_ctx *ctx)
 {
 	struct mail_index_sync_list *sync_list;
@@ -787,8 +794,10 @@ int mail_index_sync_commit(struct mail_i
 	/* refresh the mapping with newly committed external transactions
 	   and the synced expunges. sync using file handler here so that the
 	   expunge handlers get called. */
+	index->sync_commit_result = ctx->sync_commit_result;
 	if (mail_index_map(ctx->index, MAIL_INDEX_SYNC_HANDLER_FILE) <= 0)
 		ret = -1;
+	index->sync_commit_result = NULL;
 
 	want_rotate = mail_transaction_log_want_rotate(index->log);
 	if (ret == 0 &&
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index-transaction-private.h
--- a/src/lib-index/mail-index-transaction-private.h	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index-transaction-private.h	Wed Nov 18 19:58:07 2009 -0500
@@ -21,7 +21,7 @@ struct mail_index_transaction_vfuncs {
 struct mail_index_transaction_vfuncs {
 	void (*reset)(struct mail_index_transaction *t);
 	int (*commit)(struct mail_index_transaction *t,
-		      uint32_t *log_file_seq_r, uoff_t *log_file_offset_r);
+		      struct mail_index_transaction_commit_result *result_r);
 	void (*rollback)(struct mail_index_transaction *t);
 };
 
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index-transaction.c
--- a/src/lib-index/mail-index-transaction.c	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index-transaction.c	Wed Nov 18 19:58:07 2009 -0500
@@ -120,7 +120,9 @@ mail_transaction_log_file_refresh(struct
 	return 1;
 }
 
-static int mail_index_transaction_commit_real(struct mail_index_transaction *t)
+static int
+mail_index_transaction_commit_real(struct mail_index_transaction *t,
+				   uoff_t *commit_size_r)
 {
 	struct mail_transaction_log *log = t->view->index->log;
 	bool external = (t->flags & MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL) != 0;
@@ -144,6 +146,8 @@ static int mail_index_transaction_commit
 	mail_transaction_log_get_head(log, &log_seq2, &log_offset2);
 	i_assert(log_seq1 == log_seq2);
 
+	*commit_size_r = log_offset2 - log_offset1;
+
 	if ((t->flags & MAIL_INDEX_TRANSACTION_FLAG_HIDE) != 0 &&
 	    log_offset1 != log_offset2) {
 		/* mark the area covered by this transaction hidden */
@@ -154,8 +158,7 @@ static int mail_index_transaction_commit
 }
 
 static int mail_index_transaction_commit_v(struct mail_index_transaction *t,
-					   uint32_t *log_file_seq_r,
-					   uoff_t *log_file_offset_r)
+					   struct mail_index_transaction_commit_result *result_r)
 {
 	struct mail_index *index = t->view->index;
 	bool changed;
@@ -165,14 +168,10 @@ static int mail_index_transaction_commit
 		 mail_index_view_get_messages_count(t->view));
 
 	changed = MAIL_INDEX_TRANSACTION_HAS_CHANGES(t) || t->reset;
-	if (!changed) {
-		/* nothing to append */
-		ret = 0;
-	} else {
-		ret = mail_index_transaction_commit_real(t);
-	}
-	mail_transaction_log_get_head(index->log, log_file_seq_r,
-				      log_file_offset_r);
+	ret = !changed ? 0 :
+		mail_index_transaction_commit_real(t, &result_r->commit_size);
+	mail_transaction_log_get_head(index->log, &result_r->log_file_seq,
+				      &result_r->log_file_offset);
 
 	if (ret == 0 && !index->syncing && changed) {
 		/* if we're committing a normal transaction, we want to
@@ -184,7 +183,9 @@ static int mail_index_transaction_commit
 		   be done later as MAIL_INDEX_SYNC_HANDLER_FILE so that
 		   expunge handlers get run for the newly expunged messages
 		   (and sync handlers that require HANDLER_FILE as well). */
+		index->sync_commit_result = result_r;
 		(void)mail_index_refresh(index);
+		index->sync_commit_result = NULL;
 	}
 
 	mail_index_transaction_unref(&t);
@@ -198,15 +199,13 @@ static void mail_index_transaction_rollb
 
 int mail_index_transaction_commit(struct mail_index_transaction **t)
 {
-	uint32_t log_seq;
-	uoff_t log_offset;
-
-	return mail_index_transaction_commit_get_pos(t, &log_seq, &log_offset);
-}
-
-int mail_index_transaction_commit_get_pos(struct mail_index_transaction **_t,
-					  uint32_t *log_file_seq_r,
-					  uoff_t *log_file_offset_r)
+	struct mail_index_transaction_commit_result result;
+
+	return mail_index_transaction_commit_full(t, &result);
+}
+
+int mail_index_transaction_commit_full(struct mail_index_transaction **_t,
+				       struct mail_index_transaction_commit_result *result_r)
 {
 	struct mail_index_transaction *t = *_t;
 
@@ -216,7 +215,8 @@ int mail_index_transaction_commit_get_po
 	}
 
 	*_t = NULL;
-	return t->v.commit(t, log_file_seq_r, log_file_offset_r);
+	memset(result_r, 0, sizeof(*result_r));
+	return t->v.commit(t, result_r);
 }
 
 void mail_index_transaction_rollback(struct mail_index_transaction **_t)
diff -r cc5d8a5deab2 -r 75d3d4374dda src/lib-index/mail-index.h
--- a/src/lib-index/mail-index.h	Wed Nov 18 18:39:37 2009 -0500
+++ b/src/lib-index/mail-index.h	Wed Nov 18 19:58:07 2009 -0500
@@ -183,6 +183,18 @@ struct mail_index_view_sync_rec {
 	unsigned int hidden:1;
 };
 
+struct mail_index_transaction_commit_result {
+	/* seq/offset points to end of transaction */
+	uint32_t log_file_seq;
+	uoff_t log_file_offset;
+	/* number of bytes in the written transaction.
+	   all of it was written to the same file. */
+	uoff_t commit_size;
+
+	unsigned int ignored_uid_changes;
+	unsigned int ignored_modseq_changes;
+};
+
 struct mail_index;
 struct mail_index_map;
 struct mail_index_view;
@@ -245,9 +257,8 @@ mail_index_transaction_begin(struct mail
 mail_index_transaction_begin(struct mail_index_view *view,
 			     enum mail_index_transaction_flags flags);
 int mail_index_transaction_commit(struct mail_index_transaction **t);
-int mail_index_transaction_commit_get_pos(struct mail_index_transaction **t,
-					  uint32_t *log_file_seq_r,
-					  uoff_t *log_file_offset_r);
+int mail_index_transaction_commit_full(struct mail_index_transaction **t,


More information about the dovecot-cvs mailing list