# HG changeset patch # User Timo Sirainen # Date 1399469814 -10800 # Node ID ed6e472cab0e1b961bddcabdaf7c33c85503079a # Parent 2e7ac48c6072d8490b64e145323664b5697b9701 mdbox: Fixed race condition when creating a new mailbox and another process getting its GUID. 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; }