From: Timo Sirainen Date: Wed, 16 Nov 2016 01:06:31 +0000 (+0200) Subject: LAYOUT=index: Don't write corrupted mailbox names to box-name header. X-Git-Tag: 2.2.27~131 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0e6ec60d00d624caa8f66ecdff9e8f9edc91aad9;p=thirdparty%2Fdovecot%2Fcore.git 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. --- diff --git a/src/lib-storage/list/mailbox-list-index-backend.c b/src/lib-storage/list/mailbox-list-index-backend.c index d192aa034b..c9a11f869d 100644 --- a/src/lib-storage/list/mailbox-list-index-backend.c +++ b/src/lib-storage/list/mailbox-list-index-backend.c @@ -456,6 +456,15 @@ index_list_mailbox_exists(struct mailbox *box, bool auto_boxes ATTR_UNUSED, 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 @@ static int index_list_mailbox_open(struct mailbox *box) 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 @@ index_list_rename_mailbox(struct mailbox_list *_oldlist, const char *oldname, 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); diff --git a/src/lib-storage/list/mailbox-list-index-sync.c b/src/lib-storage/list/mailbox-list-index-sync.c index 8db5667df0..ccda93067d 100644 --- a/src/lib-storage/list/mailbox-list-index-sync.c +++ b/src/lib-storage/list/mailbox-list-index-sync.c @@ -377,6 +377,11 @@ mailbox_list_index_sync_update_corrupted_node(struct mailbox_list_index_sync_con 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 diff --git a/src/lib-storage/list/mailbox-list-index.c b/src/lib-storage/list/mailbox-list-index.c index bd848668a7..8217ff334c 100644 --- a/src/lib-storage/list/mailbox-list-index.c +++ b/src/lib-storage/list/mailbox-list-index.c @@ -233,6 +233,7 @@ mailbox_list_index_generate_name(struct mailbox_list_index *ilist, 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 @@ static int mailbox_list_index_parse_records(struct mailbox_list_index *ilist, /* 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)); diff --git a/src/lib-storage/list/mailbox-list-index.h b/src/lib-storage/list/mailbox-list-index.h index cf85bf1032..86b12a3db9 100644 --- a/src/lib-storage/list/mailbox-list-index.h +++ b/src/lib-storage/list/mailbox-list-index.h @@ -43,6 +43,7 @@ enum mailbox_list_index_flags { 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