mailbox-list-index.c (dovecot-2.3.16) | : | mailbox-list-index.c (dovecot-2.3.17) | ||
---|---|---|---|---|
skipping to change at line 308 | skipping to change at line 308 | |||
const char **error_r) | const char **error_r) | |||
{ | { | |||
struct mailbox_list_index_node *node, *parent; | struct mailbox_list_index_node *node, *parent; | |||
HASH_TABLE(struct mailbox_list_index_node *, | HASH_TABLE(struct mailbox_list_index_node *, | |||
struct mailbox_list_index_node *) duplicate_hash; | struct mailbox_list_index_node *) duplicate_hash; | |||
const struct mail_index_record *rec; | const struct mail_index_record *rec; | |||
const struct mailbox_list_index_record *irec; | const struct mailbox_list_index_record *irec; | |||
const void *data; | const void *data; | |||
bool expunged; | bool expunged; | |||
uint32_t seq, uid, count; | uint32_t seq, uid, count; | |||
HASH_TABLE(uint8_t *, struct mailbox_list_index_node *) duplicate_guid; | ||||
*error_r = NULL; | *error_r = NULL; | |||
hash_table_create(&duplicate_hash, default_pool, 0, | pool_t dup_pool = | |||
pool_alloconly_create(MEMPOOL_GROWING"duplicate pool", 2048); | ||||
hash_table_create(&duplicate_hash, dup_pool, 0, | ||||
mailbox_list_index_node_hash, | mailbox_list_index_node_hash, | |||
mailbox_list_index_node_cmp); | mailbox_list_index_node_cmp); | |||
count = mail_index_view_get_messages_count(view); | count = mail_index_view_get_messages_count(view); | |||
if (!ilist->has_backing_store) | ||||
hash_table_create(&duplicate_guid, dup_pool, 0, guid_128_hash, | ||||
guid_128_cmp); | ||||
for (seq = 1; seq <= count; seq++) { | for (seq = 1; seq <= count; seq++) { | |||
node = p_new(ilist->mailbox_pool, | node = p_new(ilist->mailbox_pool, | |||
struct mailbox_list_index_node, 1); | struct mailbox_list_index_node, 1); | |||
rec = mail_index_lookup(view, seq); | rec = mail_index_lookup(view, seq); | |||
node->uid = rec->uid; | node->uid = rec->uid; | |||
node->flags = rec->flags; | node->flags = rec->flags; | |||
mail_index_lookup_ext(view, seq, ilist->ext_id, | mail_index_lookup_ext(view, seq, ilist->ext_id, | |||
&data, &expunged); | &data, &expunged); | |||
if (data == NULL) { | if (data == NULL) { | |||
skipping to change at line 371 | skipping to change at line 378 | |||
if (!ilist->has_backing_store && !guid_128_is_empty(irec->guid) & & | if (!ilist->has_backing_store && !guid_128_is_empty(irec->guid) & & | |||
(rec->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT | | (rec->flags & (MAILBOX_LIST_INDEX_FLAG_NONEXISTENT | | |||
MAILBOX_LIST_INDEX_FLAG_NOSELECT)) != 0) { | MAILBOX_LIST_INDEX_FLAG_NOSELECT)) != 0) { | |||
node->flags &= ENUM_NEGATE(MAILBOX_LIST_INDEX_FLAG_NONEXI STENT | MAILBOX_LIST_INDEX_FLAG_NOSELECT); | node->flags &= ENUM_NEGATE(MAILBOX_LIST_INDEX_FLAG_NONEXI STENT | MAILBOX_LIST_INDEX_FLAG_NOSELECT); | |||
*error_r = t_strdup_printf( | *error_r = t_strdup_printf( | |||
"non-selectable mailbox '%s' (uid=%u) already has GUID - " | "non-selectable mailbox '%s' (uid=%u) already has GUID - " | |||
"marking it selectable", node->raw_name, node->ui d); | "marking it selectable", node->raw_name, node->ui d); | |||
node->corrupted_flags = TRUE; | node->corrupted_flags = TRUE; | |||
} | } | |||
if (!ilist->has_backing_store && !guid_128_is_empty(irec->guid)) | ||||
{ | ||||
struct mailbox_list_index_node *dup_node; | ||||
uint8_t *guid_p = p_memdup(dup_pool, irec->guid, | ||||
sizeof(guid_128_t)); | ||||
if ((dup_node = hash_table_lookup(duplicate_guid, guid_p) | ||||
) != NULL) { | ||||
*error_r = t_strdup_printf( | ||||
"duplicate GUID %s for mailbox '% | ||||
s' and '%s'", | ||||
guid_128_to_string(guid_p), | ||||
node->raw_name, | ||||
dup_node->raw_name); | ||||
node->corrupted_ext = TRUE; | ||||
ilist->corrupted_names_or_parents = TRUE; | ||||
ilist->call_corruption_callback = TRUE; | ||||
} else { | ||||
hash_table_insert(duplicate_guid, guid_p, node); | ||||
} | ||||
} | ||||
hash_table_insert(ilist->mailbox_hash, | hash_table_insert(ilist->mailbox_hash, | |||
POINTER_CAST(node->uid), node); | POINTER_CAST(node->uid), node); | |||
} | } | |||
/* do a second scan to create the actual mailbox tree hierarchy. | /* do a second scan to create the actual mailbox tree hierarchy. | |||
this is needed because the parent_uid may be smaller or higher than | this is needed because the parent_uid may be smaller or higher than | |||
the current node's uid */ | the current node's uid */ | |||
if (*error_r != NULL && ilist->has_backing_store) | if (*error_r != NULL && ilist->has_backing_store) | |||
count = 0; | count = 0; | |||
for (seq = 1; seq <= count; seq++) { | for (seq = 1; seq <= count; seq++) { | |||
skipping to change at line 445 | skipping to change at line 470 | |||
*error_r = t_strdup_printf( | *error_r = t_strdup_printf( | |||
"Duplicate mailbox '%s' in index, renaming to %s" , | "Duplicate mailbox '%s' in index, renaming to %s" , | |||
old_name, node->raw_name); | old_name, node->raw_name); | |||
} | } | |||
if (node->parent == NULL) { | if (node->parent == NULL) { | |||
node->next = ilist->mailbox_tree; | node->next = ilist->mailbox_tree; | |||
ilist->mailbox_tree = node; | ilist->mailbox_tree = node; | |||
} | } | |||
} | } | |||
hash_table_destroy(&duplicate_hash); | hash_table_destroy(&duplicate_hash); | |||
if (!ilist->has_backing_store) | ||||
hash_table_destroy(&duplicate_guid); | ||||
pool_unref(&dup_pool); | ||||
return *error_r == NULL ? 0 : -1; | return *error_r == NULL ? 0 : -1; | |||
} | } | |||
int mailbox_list_index_parse(struct mailbox_list *list, | int mailbox_list_index_parse(struct mailbox_list *list, | |||
struct mail_index_view *view, bool force) | struct mail_index_view *view, bool force) | |||
{ | { | |||
struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(list); | struct mailbox_list_index *ilist = INDEX_LIST_CONTEXT_REQUIRE(list); | |||
const struct mail_index_header *hdr; | const struct mail_index_header *hdr; | |||
const char *error; | const char *error; | |||
skipping to change at line 651 | skipping to change at line 679 | |||
enum mail_storage_list_index_rebuild_reason reason; | enum mail_storage_list_index_rebuild_reason reason; | |||
int ret; | int ret; | |||
if (ilist->call_corruption_callback) | if (ilist->call_corruption_callback) | |||
reason = MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_CORRUPTED; | reason = MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_CORRUPTED; | |||
else if (ilist->rebuild_on_missing_inbox) | else if (ilist->rebuild_on_missing_inbox) | |||
reason = MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_NO_INBOX; | reason = MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_NO_INBOX; | |||
else | else | |||
return 0; | return 0; | |||
if (list->disable_rebuild_on_corruption) | ||||
return 0; | ||||
/* make sure we don't recurse */ | /* make sure we don't recurse */ | |||
if (ilist->handling_corruption) | if (ilist->handling_corruption) | |||
return 0; | return 0; | |||
ilist->handling_corruption = TRUE; | ilist->handling_corruption = TRUE; | |||
/* Perform the rebuilding locked. Note that if we're here because | /* Perform the rebuilding locked. Note that if we're here because | |||
INBOX wasn't found, this may be because another process is in the | INBOX wasn't found, this may be because another process is in the | |||
middle of creating it. Waiting for the lock here makes sure that | middle of creating it. Waiting for the lock here makes sure that | |||
we don't start rebuilding before it's finished. In that case the | we don't start rebuilding before it's finished. In that case the | |||
rebuild is a bit unnecessary, but harmless (and avoiding the rebuild | rebuild is a bit unnecessary, but harmless (and avoiding the rebuild | |||
End of changes. 6 change blocks. | ||||
1 lines changed or deleted | 35 lines changed or added |