dovecot-2.2: mbox: Fixed assert-crash due to wrong transaction_c...

dovecot at dovecot.org dovecot at dovecot.org
Sun Sep 22 06:31:01 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/afc8c800f6ca
changeset: 16816:afc8c800f6ca
user:      Timo Sirainen <tss at iki.fi>
date:      Sun Sep 22 06:30:47 2013 +0300
description:
mbox: Fixed assert-crash due to wrong transaction_count handling.
This happened only when messages had been expunged by another session just
before saving a new message.

diffstat:

 src/lib-storage/index/mbox/mbox-storage.c |   3 ++-
 src/lib-storage/mail-storage.c            |  15 ++++++++++-----
 2 files changed, 12 insertions(+), 6 deletions(-)

diffs (61 lines):

diff -r 1cd94c4cd456 -r afc8c800f6ca src/lib-storage/index/mbox/mbox-storage.c
--- a/src/lib-storage/index/mbox/mbox-storage.c	Sun Sep 22 04:41:50 2013 +0300
+++ b/src/lib-storage/index/mbox/mbox-storage.c	Sun Sep 22 06:30:47 2013 +0300
@@ -737,7 +737,8 @@
 	if (lock_id2 != 0)
 		mbox_unlock(mbox, lock_id2);
 	if (mbox->mbox_global_lock_id == 0) {
-		i_assert(mbox->box.transaction_count > 0 ||
+		i_assert(mbox->box.transaction_count > 0);
+		i_assert(mbox->box.transaction_count > 1 ||
 			 mbox->external_transactions > 0 ||
 			 mbox->mbox_lock_type == F_UNLCK);
 	} else {
diff -r 1cd94c4cd456 -r afc8c800f6ca src/lib-storage/mail-storage.c
--- a/src/lib-storage/mail-storage.c	Sun Sep 22 04:41:50 2013 +0300
+++ b/src/lib-storage/mail-storage.c	Sun Sep 22 06:30:47 2013 +0300
@@ -1836,15 +1836,15 @@
 	struct mail_transaction_commit_changes *changes_r)
 {
 	struct mailbox_transaction_context *t = *_t;
+	struct mailbox *box = t->box;
 	unsigned int save_count = t->save_count;
 	int ret;
 
-	t->box->transaction_count--;
 	changes_r->pool = NULL;
 
 	*_t = NULL;
 	T_BEGIN {
-		ret = t->box->v.transaction_commit(t, changes_r);
+		ret = box->v.transaction_commit(t, changes_r);
 	} T_END;
 	/* either all the saved messages get UIDs or none, because a) we
 	   failed, b) MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS not set,
@@ -1852,6 +1852,11 @@
 	i_assert(ret < 0 ||
 		 seq_range_count(&changes_r->saved_uids) == save_count ||
 		 array_count(&changes_r->saved_uids) == 0);
+	/* decrease the transaction count only after transaction_commit().
+	   that way if it creates and destroys transactions internally, we
+	   don't see transaction_count=0 until the parent transaction is fully
+	   finished */
+	box->transaction_count--;
 	if (ret < 0 && changes_r->pool != NULL)
 		pool_unref(&changes_r->pool);
 	return ret;
@@ -1860,11 +1865,11 @@
 void mailbox_transaction_rollback(struct mailbox_transaction_context **_t)
 {
 	struct mailbox_transaction_context *t = *_t;
-
-	t->box->transaction_count--;
+	struct mailbox *box = t->box;
 
 	*_t = NULL;
-	t->box->v.transaction_rollback(t);
+	box->v.transaction_rollback(t);
+	box->transaction_count--;
 }
 
 unsigned int mailbox_transaction_get_count(const struct mailbox *box)


More information about the dovecot-cvs mailing list