dovecot-2.2: LAYOUT=index: Fixed race condition during mailbox c...
dovecot at dovecot.org
dovecot at dovecot.org
Fri Oct 11 18:55:10 EEST 2013
details: http://hg.dovecot.org/dovecot-2.2/rev/ab341f7509b5
changeset: 16842:ab341f7509b5
user: Timo Sirainen <tss at iki.fi>
date: Fri Oct 11 18:54:36 2013 +0300
description:
LAYOUT=index: Fixed race condition during mailbox creation.
diffstat:
src/lib-storage/list/mailbox-list-index-backend.c | 33 ++++++++++++----------
src/lib-storage/list/mailbox-list-index-sync.c | 4 ++
src/lib-storage/list/mailbox-list-index.h | 1 +
3 files changed, 23 insertions(+), 15 deletions(-)
diffs (141 lines):
diff -r 4b0a736bc40c -r ab341f7509b5 src/lib-storage/list/mailbox-list-index-backend.c
--- a/src/lib-storage/list/mailbox-list-index-backend.c Fri Oct 11 12:31:48 2013 +0300
+++ b/src/lib-storage/list/mailbox-list-index-backend.c Fri Oct 11 18:54:36 2013 +0300
@@ -136,7 +136,10 @@
}
return -1;
}
- view = mail_index_view_open(ilist->index);
+ /* we could get here during sync from
+ index_list_mailbox_create_selectable() */
+ view = ilist->sync_ctx == NULL ? mail_index_view_open(ilist->index) :
+ ilist->sync_ctx->view;
if (!mail_index_lookup_seq(view, node->uid, &seq))
i_panic("mailbox list index: lost uid=%u", node->uid);
if (!mailbox_list_index_status(_list, view, seq, 0,
@@ -149,7 +152,8 @@
*path_r = index_get_guid_path(_list, root_dir, mailbox_guid);
ret = 1;
}
- mail_index_view_close(&view);
+ if (ilist->sync_ctx == NULL)
+ mail_index_view_close(&view);
return ret;
}
@@ -234,20 +238,23 @@
}
static int
-index_list_mailbox_create_selectable(struct index_mailbox_list *list,
- const char *name, guid_128_t mailbox_guid)
+index_list_mailbox_create_selectable(struct mailbox *box,
+ const struct mailbox_update *update)
{
+ struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
+ struct index_mailbox_list *list =
+ (struct index_mailbox_list *)box->list;
struct mailbox_list_index_sync_context *sync_ctx;
struct mailbox_list_index_record rec;
struct mailbox_list_index_node *node;
const void *data;
- bool expunged, created;
+ bool expunged, created, success;
uint32_t seq;
if (mailbox_list_index_sync_begin(&list->list, &sync_ctx) < 0)
return -1;
- seq = mailbox_list_index_sync_name(sync_ctx, name, &node, &created);
+ seq = mailbox_list_index_sync_name(sync_ctx, box->name, &node, &created);
if (!created &&
(node->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT |
MAILBOX_LIST_INDEX_FLAG_NOSELECT)) == 0) {
@@ -266,11 +273,12 @@
node->flags = 0;
mail_index_update_flags(sync_ctx->trans, seq, MODIFY_REPLACE, 0);
- memcpy(rec.guid, mailbox_guid, sizeof(rec.guid));
+ memcpy(rec.guid, update->mailbox_guid, sizeof(rec.guid));
mail_index_update_ext(sync_ctx->trans, seq, sync_ctx->ilist->ext_id,
&rec, NULL);
- if (mailbox_list_index_sync_end(&sync_ctx, TRUE) < 0)
+ success = ibox->module_ctx.super.create_box(box, update, FALSE) == 0;
+ if (mailbox_list_index_sync_end(&sync_ctx, success) < 0)
return -1;
return 1;
}
@@ -279,7 +287,6 @@
index_list_mailbox_create(struct mailbox *box,
const struct mailbox_update *update, bool directory)
{
- struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box);
struct index_mailbox_list *list =
(struct index_mailbox_list *)box->list;
struct mailbox_update new_update;
@@ -306,14 +313,11 @@
new_update = *update;
if (guid_128_is_empty(new_update.mailbox_guid))
guid_128_generate(new_update.mailbox_guid);
- ret = index_list_mailbox_create_selectable(list, box->name,
- new_update.mailbox_guid);
+ ret = index_list_mailbox_create_selectable(box, &new_update);
if (ret < 0) {
mail_storage_copy_list_error(box->storage, box->list);
return -1;
}
- /* the storage backend needs to use the same GUID */
- update = &new_update;
} else {
ret = 0;
}
@@ -323,8 +327,7 @@
"Mailbox already exists");
return -1;
}
- return directory ? 0 :
- ibox->module_ctx.super.create_box(box, update, directory);
+ return 0;
}
static int
diff -r 4b0a736bc40c -r ab341f7509b5 src/lib-storage/list/mailbox-list-index-sync.c
--- a/src/lib-storage/list/mailbox-list-index-sync.c Fri Oct 11 12:31:48 2013 +0300
+++ b/src/lib-storage/list/mailbox-list-index-sync.c Fri Oct 11 18:54:36 2013 +0300
@@ -236,6 +236,8 @@
struct mail_index_transaction *trans;
const struct mail_index_header *hdr;
+ i_assert(!ilist->syncing);
+
if (mail_index_sync_begin(ilist->index, &index_sync_ctx, &view, &trans,
MAIL_INDEX_SYNC_FLAG_AVOID_FLAG_UPDATES) < 0) {
mailbox_list_index_set_index_error(list);
@@ -269,6 +271,7 @@
&uid_validity, sizeof(uid_validity), TRUE);
}
sync_ctx->view = mail_index_transaction_open_updated_view(trans);
+ ilist->sync_ctx = sync_ctx;
ilist->syncing = TRUE;
*sync_ctx_r = sync_ctx;
@@ -370,6 +373,7 @@
ret = -1;
}
sync_ctx->ilist->syncing = FALSE;
+ sync_ctx->ilist->sync_ctx = NULL;
i_free(sync_ctx);
return ret;
}
diff -r 4b0a736bc40c -r ab341f7509b5 src/lib-storage/list/mailbox-list-index.h
--- a/src/lib-storage/list/mailbox-list-index.h Fri Oct 11 12:31:48 2013 +0300
+++ b/src/lib-storage/list/mailbox-list-index.h Fri Oct 11 18:54:36 2013 +0300
@@ -92,6 +92,7 @@
HASH_TABLE(void *, char *) mailbox_names;
uint32_t highest_name_id;
+ struct mailbox_list_index_sync_context *sync_ctx;
uint32_t sync_log_file_seq;
uoff_t sync_log_file_offset;
uint32_t sync_stamp;
More information about the dovecot-cvs
mailing list