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