dovecot-2.0: mdbox: Fixed a race condition when expunging messages.
dovecot at dovecot.org
dovecot at dovecot.org
Sun Mar 14 15:02:30 EET 2010
details: http://hg.dovecot.org/dovecot-2.0/rev/3f43b5c47a0e
changeset: 10907:3f43b5c47a0e
user: Timo Sirainen <tss at iki.fi>
date: Sun Mar 14 15:02:28 2010 +0200
description:
mdbox: Fixed a race condition when expunging messages.
diffstat:
src/lib-storage/index/dbox-multi/mdbox-sync.c | 32 +++++++++++++++++++++++++++-----
1 files changed, 27 insertions(+), 5 deletions(-)
diffs (67 lines):
diff -r 841af633f8d0 -r 3f43b5c47a0e src/lib-storage/index/dbox-multi/mdbox-sync.c
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.c Sun Mar 14 03:47:34 2010 +0200
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c Sun Mar 14 15:02:28 2010 +0200
@@ -84,24 +84,39 @@
return 0;
}
-static void dbox_sync_mark_expunges(struct mdbox_sync_context *ctx)
+static int dbox_sync_mark_expunges(struct mdbox_sync_context *ctx)
{
+ enum mail_index_transaction_flags flags =
+ MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
struct mailbox *box = &ctx->mbox->box;
+ struct mail_index_transaction *trans;
struct seq_range_iter iter;
unsigned int n;
const void *data;
uint32_t seq, uid;
+ /* use a separate transaction here so that we can commit the changes
+ during map transaction */
+ trans = mail_index_transaction_begin(ctx->sync_view, flags);
seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
while (seq_range_array_iter_nth(&iter, n++, &seq)) {
mail_index_lookup_uid(ctx->sync_view, seq, &uid);
mail_index_lookup_ext(ctx->sync_view, seq,
ctx->mbox->guid_ext_id, &data, NULL);
- mail_index_expunge_guid(ctx->trans, seq, data);
+ mail_index_expunge_guid(trans, seq, data);
+ }
+ if (mail_index_transaction_commit(&trans) < 0)
+ return -1;
- if (box->v.sync_notify != NULL)
+ if (box->v.sync_notify != NULL) {
+ /* do notifications after commit finished successfully */
+ seq_range_array_iter_init(&iter, &ctx->expunged_seqs); n = 0;
+ while (seq_range_array_iter_nth(&iter, n++, &seq)) {
+ mail_index_lookup_uid(ctx->sync_view, seq, &uid);
box->v.sync_notify(box, uid, MAILBOX_SYNC_TYPE_EXPUNGE);
+ }
}
+ return 0;
}
static int mdbox_sync_index_finish_expunges(struct mdbox_sync_context *ctx)
@@ -112,11 +127,18 @@
map_trans = dbox_map_transaction_begin(ctx->mbox->storage->map, FALSE);
ret = dbox_map_update_refcounts(map_trans, &ctx->expunged_map_uids, -1);
if (ret == 0) {
+ /* write refcount changes to map index */
ret = dbox_map_transaction_commit(map_trans);
- if (ret == 0)
- dbox_sync_mark_expunges(ctx);
+ if (ret == 0) {
+ /* write changes to mailbox index */
+ ret = dbox_sync_mark_expunges(ctx);
+ }
}
+ /* this finally finishes the map sync and makes it clear that the
+ map transaction was successfully finished. */
+ if (ret < 0)
+ dbox_map_transaction_set_failed(map_trans);
dbox_map_transaction_free(&map_trans);
return ret;
}
More information about the dovecot-cvs
mailing list