changeset 16781:98702a45784c

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.
author Timo Sirainen <tss@iki.fi>
date Fri, 20 Sep 2013 03:54:31 +0300
parents d7627178a7f2
children ac832f051b49
files src/lib-storage/index/dbox-multi/mdbox-storage.c src/lib-storage/index/dbox-multi/mdbox-storage.h src/lib-storage/index/dbox-multi/mdbox-sync.c src/lib-storage/index/dbox-single/sdbox-storage.c src/lib-storage/index/dbox-single/sdbox-storage.h src/lib-storage/index/dbox-single/sdbox-sync.c
diffstat 6 files changed, 29 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- 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;
--- 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);
--- 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;
 	}
--- 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;
--- 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 *
--- 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));