dovecot-2.2: mdbox: Fixed race condition when creating a new mai...

dovecot at dovecot.org dovecot at dovecot.org
Wed May 7 13:37:36 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/ed6e472cab0e
changeset: 17331:ed6e472cab0e
user:      Timo Sirainen <tss at iki.fi>
date:      Wed May 07 16:36:54 2014 +0300
description:
mdbox: Fixed race condition when creating a new mailbox and another process getting its GUID.

diffstat:

 src/lib-storage/index/dbox-common/dbox-storage.c |  14 +++++++++++---
 src/lib-storage/index/dbox-common/dbox-storage.h |   2 ++
 src/lib-storage/index/dbox-multi/mdbox-storage.c |  12 ++++++++----
 3 files changed, 21 insertions(+), 7 deletions(-)

diffs (73 lines):

diff -r 2e7ac48c6072 -r ed6e472cab0e src/lib-storage/index/dbox-common/dbox-storage.c
--- a/src/lib-storage/index/dbox-common/dbox-storage.c	Wed May 07 13:02:29 2014 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-storage.c	Wed May 07 16:36:54 2014 +0300
@@ -255,9 +255,6 @@
 			const struct mailbox_update *update, bool directory)
 {
 	struct dbox_storage *storage = (struct dbox_storage *)box->storage;
-	struct mail_index_sync_ctx *sync_ctx;
-	struct mail_index_view *view;
-	struct mail_index_transaction *trans;
 	const char *alt_path;
 	struct stat st;
 	int ret;
@@ -290,6 +287,17 @@
 		}
 		/* dir is empty, ignore it */
 	}
+	return dbox_mailbox_create_indexes(box, update);
+}
+
+int dbox_mailbox_create_indexes(struct mailbox *box,
+				const struct mailbox_update *update)
+{
+	struct dbox_storage *storage = (struct dbox_storage *)box->storage;
+	struct mail_index_sync_ctx *sync_ctx;
+	struct mail_index_view *view;
+	struct mail_index_transaction *trans;
+	int ret;
 
 	/* use syncing as a lock */
 	ret = mail_index_sync_begin(box->index, &sync_ctx, &view, &trans, 0);
diff -r 2e7ac48c6072 -r ed6e472cab0e src/lib-storage/index/dbox-common/dbox-storage.h
--- a/src/lib-storage/index/dbox-common/dbox-storage.h	Wed May 07 13:02:29 2014 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-storage.h	Wed May 07 16:36:54 2014 +0300
@@ -73,6 +73,8 @@
 int dbox_mailbox_open(struct mailbox *box);
 int dbox_mailbox_create(struct mailbox *box,
 			const struct mailbox_update *update, bool directory);
+int dbox_mailbox_create_indexes(struct mailbox *box,
+				const struct mailbox_update *update);
 int dbox_verify_alt_storage(struct mailbox_list *list);
 bool dbox_header_have_flag(struct mailbox *box, uint32_t ext_id,
 			   unsigned int flags_offset, uint8_t flag);
diff -r 2e7ac48c6072 -r ed6e472cab0e src/lib-storage/index/dbox-multi/mdbox-storage.c
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.c	Wed May 07 13:02:29 2014 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c	Wed May 07 16:36:54 2014 +0300
@@ -379,10 +379,15 @@
 
 	/* there's a race condition between mkdir and getting the mailbox GUID.
 	   normally this is handled by mdbox syncing, but GUID can be looked up
-	   without syncing. when mbox->creating=TRUE, the errors are hidden
-	   and we'll simply finish the mailbox creation */
+	   without syncing. when we detect this situation we'll try to finish
+	   creating the indexes first, which usually means just waiting for
+	   the sync lock to get unlocked by the other process creating them. */
 	idx_hdr = mail_index_get_header(mbox->box.view);
-	mbox->creating = idx_hdr->uid_validity == 0 && idx_hdr->next_uid == 1;
+	if (idx_hdr->uid_validity == 0 && idx_hdr->next_uid == 1) {
+		if (dbox_mailbox_create_indexes(&mbox->box, NULL) < 0)
+			return -1;
+	}
+
 	if (mdbox_read_header(mbox, &hdr, &need_resize) < 0)
 		memset(&hdr, 0, sizeof(hdr));
 
@@ -394,7 +399,6 @@
 	}
 	if (ret == 0)
 		memcpy(guid_r, hdr.mailbox_guid, GUID_128_SIZE);
-	mbox->creating = FALSE;
 	return ret;
 }
 


More information about the dovecot-cvs mailing list