Mercurial > dovecot > core-2.2
changeset 21137:6bdcc7190a55
LAYOUT=index: Don't write corrupted mailbox names to box-name header.
This way when opening a mailbox the box-name header isn't overwritten by
a corrupted name.
Keep track of the corrupted names with MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME
flag in list index records. The flag isn't removed until the mailbox is
renamed.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Wed, 16 Nov 2016 03:06:31 +0200 |
parents | 0346bbd0fdc1 |
children | b24657e6abe7 |
files | src/lib-storage/list/mailbox-list-index-backend.c src/lib-storage/list/mailbox-list-index-sync.c src/lib-storage/list/mailbox-list-index.c src/lib-storage/list/mailbox-list-index.h |
diffstat | 4 files changed, 25 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/list/mailbox-list-index-backend.c Wed Nov 16 03:01:22 2016 +0200 +++ b/src/lib-storage/list/mailbox-list-index-backend.c Wed Nov 16 03:06:31 2016 +0200 @@ -456,6 +456,15 @@ return 0; } +static bool mailbox_has_corrupted_name(struct mailbox *box) +{ + struct mailbox_list_index_node *node; + + node = mailbox_list_index_lookup(box->list, box->name); + return node != NULL && + (node->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0; +} + static int index_list_mailbox_open(struct mailbox *box) { struct index_list_mailbox *ibox = INDEX_LIST_STORAGE_CONTEXT(box); @@ -491,7 +500,7 @@ if (name_hdr_size == box_name_len && memcmp(box_zerosep_name, name_hdr, box_name_len) == 0) { /* Same mailbox name */ - } else { + } else if (!mailbox_has_corrupted_name(box)) { /* Mailbox name changed - update */ struct mail_index_transaction *trans = mail_index_transaction_begin(box->view, 0); @@ -699,6 +708,13 @@ oldrec.name_id = newrec.name_id; oldrec.parent_uid = newrec.parent_uid; + if ((newnode->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0) { + /* mailbox is renamed - clear away the corruption flag so the + new name will be written to the mailbox index header. */ + newnode->flags &= ~MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME; + mail_index_update_flags(sync_ctx->trans, oldseq, MODIFY_REMOVE, + MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME); + } mail_index_update_ext(sync_ctx->trans, oldseq, sync_ctx->ilist->ext_id, &oldrec, NULL); mail_index_expunge(sync_ctx->trans, newseq);
--- a/src/lib-storage/list/mailbox-list-index-sync.c Wed Nov 16 03:01:22 2016 +0200 +++ b/src/lib-storage/list/mailbox-list-index-sync.c Wed Nov 16 03:06:31 2016 +0200 @@ -377,6 +377,11 @@ sync_ctx->ilist->ext_id, &irec, NULL); node->corrupted_parent = FALSE; } + if ((node->flags & MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME) != 0) { + /* rely on lib-index to drop unnecessary updates */ + mail_index_update_flags(sync_ctx->trans, seq, MODIFY_ADD, + MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME); + } } static void
--- a/src/lib-storage/list/mailbox-list-index.c Wed Nov 16 03:01:22 2016 +0200 +++ b/src/lib-storage/list/mailbox-list-index.c Wed Nov 16 03:06:31 2016 +0200 @@ -233,6 +233,7 @@ name = p_strdup_printf(ilist->mailbox_pool, "unknown-%s", guid_128_to_string(guid)); node->name = name; + node->flags |= MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME; hash_table_insert(ilist->mailbox_names, POINTER_CAST(node->name_id), name); @@ -372,6 +373,7 @@ /* we have only the mailbox list index and this node may have a different GUID, so rename it. */ guid_128_generate(guid); + node->flags |= MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME; node->name = p_strdup_printf(ilist->mailbox_pool, "%s-duplicate-%s", node->name, guid_128_to_string(guid));
--- a/src/lib-storage/list/mailbox-list-index.h Wed Nov 16 03:01:22 2016 +0200 +++ b/src/lib-storage/list/mailbox-list-index.h Wed Nov 16 03:06:31 2016 +0200 @@ -43,6 +43,7 @@ MAILBOX_LIST_INDEX_FLAG_NONEXISTENT = MAIL_DELETED, MAILBOX_LIST_INDEX_FLAG_NOSELECT = MAIL_DRAFT, MAILBOX_LIST_INDEX_FLAG_NOINFERIORS = MAIL_ANSWERED, + MAILBOX_LIST_INDEX_FLAG_CORRUPTED_NAME = MAIL_SEEN, /* set during syncing for mailboxes that still exist */ MAILBOX_LIST_INDEX_FLAG_SYNC_EXISTS = MAIL_FLAGGED