dovecot-2.2: dbox: Fixed "UIDVALIDITY=0" error race condition.

dovecot at dovecot.org dovecot at dovecot.org
Fri Sep 20 03:54:49 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/98702a45784c
changeset: 16781:98702a45784c
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Sep 20 03:54:31 2013 +0300
description:
dbox: Fixed "UIDVALIDITY=0" error race condition.
If session 1 had mkdir()ed but not yet created the initial index, while
session 2 attempted to open the mailbox, it would create an empty index and
log the error.

diffstat:

 src/lib-storage/index/dbox-multi/mdbox-storage.c  |   6 +++---
 src/lib-storage/index/dbox-multi/mdbox-storage.h  |   3 +++
 src/lib-storage/index/dbox-multi/mdbox-sync.c     |  10 +++++++++-
 src/lib-storage/index/dbox-single/sdbox-storage.c |   7 +++----
 src/lib-storage/index/dbox-single/sdbox-storage.h |   3 +++
 src/lib-storage/index/dbox-single/sdbox-sync.c    |   8 ++++++++
 6 files changed, 29 insertions(+), 8 deletions(-)

diffs (98 lines):

diff -r d7627178a7f2 -r 98702a45784c src/lib-storage/index/dbox-multi/mdbox-storage.c
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.c	Fri Sep 20 03:41:51 2013 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c	Fri Sep 20 03:54:31 2013 +0300
@@ -319,9 +319,9 @@
 	return 0;
 }
 
-static int mdbox_mailbox_create_indexes(struct mailbox *box,
-					const struct mailbox_update *update,
-					struct mail_index_transaction *trans)
+int mdbox_mailbox_create_indexes(struct mailbox *box,
+				 const struct mailbox_update *update,
+				 struct mail_index_transaction *trans)
 {
 	struct mdbox_mailbox *mbox = (struct mdbox_mailbox *)box;
 	int ret;
diff -r d7627178a7f2 -r 98702a45784c src/lib-storage/index/dbox-multi/mdbox-storage.h
--- a/src/lib-storage/index/dbox-multi/mdbox-storage.h	Fri Sep 20 03:41:51 2013 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-storage.h	Fri Sep 20 03:54:31 2013 +0300
@@ -75,6 +75,9 @@
 void mdbox_update_header(struct mdbox_mailbox *mbox,
 			 struct mail_index_transaction *trans,
 			 const struct mailbox_update *update) ATTR_NULL(3);
+int mdbox_mailbox_create_indexes(struct mailbox *box,
+				 const struct mailbox_update *update,
+				 struct mail_index_transaction *trans);
 
 struct mail_save_context *
 mdbox_save_alloc(struct mailbox_transaction_context *_t);
diff -r d7627178a7f2 -r 98702a45784c src/lib-storage/index/dbox-multi/mdbox-sync.c
--- a/src/lib-storage/index/dbox-multi/mdbox-sync.c	Fri Sep 20 03:41:51 2013 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-sync.c	Fri Sep 20 03:54:31 2013 +0300
@@ -137,8 +137,16 @@
 	hdr = mail_index_get_header(ctx->sync_view);
 	if (hdr->uid_validity == 0) {
 		/* newly created index file */
+		if (hdr->next_uid == 1) {
+			/* could be just a race condition where we opened the
+			   mailbox between mkdir and index creation. fix this
+			   silently. */
+			if (mdbox_mailbox_create_indexes(box, NULL, ctx->trans) < 0)
+				return -1;
+			return 1;
+		}
 		mail_storage_set_critical(box->storage,
-			"Mailbox %s: Corrupted index, uidvalidity=0",
+			"Mailbox %s: Broken index: missing UIDVALIDITY",
 			box->vname);
 		return 0;
 	}
diff -r d7627178a7f2 -r 98702a45784c src/lib-storage/index/dbox-single/sdbox-storage.c
--- a/src/lib-storage/index/dbox-single/sdbox-storage.c	Fri Sep 20 03:41:51 2013 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.c	Fri Sep 20 03:54:31 2013 +0300
@@ -211,10 +211,9 @@
 	       sizeof(mbox->mailbox_guid));
 }
 
-static int ATTR_NULL(2, 3)
-sdbox_mailbox_create_indexes(struct mailbox *box,
-			     const struct mailbox_update *update,
-			     struct mail_index_transaction *trans)
+int sdbox_mailbox_create_indexes(struct mailbox *box,
+				 const struct mailbox_update *update,
+				 struct mail_index_transaction *trans)
 {
 	struct sdbox_mailbox *mbox = (struct sdbox_mailbox *)box;
 	struct mail_index_transaction *new_trans = NULL;
diff -r d7627178a7f2 -r 98702a45784c src/lib-storage/index/dbox-single/sdbox-storage.h
--- a/src/lib-storage/index/dbox-single/sdbox-storage.h	Fri Sep 20 03:41:51 2013 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-storage.h	Fri Sep 20 03:54:31 2013 +0300
@@ -41,6 +41,9 @@
 int sdbox_read_header(struct sdbox_mailbox *mbox,
 		      struct sdbox_index_header *hdr, bool log_error,
 		      bool *need_resize_r);
+int sdbox_mailbox_create_indexes(struct mailbox *box,
+				 const struct mailbox_update *update,
+				 struct mail_index_transaction *trans);
 void sdbox_set_mailbox_corrupted(struct mailbox *box);
 
 struct mail_save_context *
diff -r d7627178a7f2 -r 98702a45784c src/lib-storage/index/dbox-single/sdbox-sync.c
--- a/src/lib-storage/index/dbox-single/sdbox-sync.c	Fri Sep 20 03:41:51 2013 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-sync.c	Fri Sep 20 03:54:31 2013 +0300
@@ -107,6 +107,14 @@
 	hdr = mail_index_get_header(ctx->sync_view);
 	if (hdr->uid_validity == 0) {
 		/* newly created index file */
+		if (hdr->next_uid == 1) {
+			/* could be just a race condition where we opened the
+			   mailbox between mkdir and index creation. fix this
+			   silently. */
+			if (sdbox_mailbox_create_indexes(box, NULL, ctx->trans) < 0)
+				return -1;
+			return 1;
+		}
 		mail_storage_set_critical(box->storage,
 			"sdbox %s: Broken index: missing UIDVALIDITY",
 			mailbox_get_path(box));


More information about the dovecot-cvs mailing list