mail-index-sync-update.c revision f172291ed740e6af3ce3e7c9c2ef0fe1d3ad7963
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2004 Timo Sirainen */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic void mail_index_sync_replace_map(struct mail_index_view *view,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen mail_index_unmap(view->index, view->index->map);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenmail_index_header_update_counts(struct mail_index_header *hdr,
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen if (((old_flags ^ new_flags) & MAIL_RECENT) != 0) {
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen /* different recent-flag */
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen hdr->first_recent_uid_lowwater = hdr->next_uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (((old_flags ^ new_flags) & MAIL_SEEN) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* different seen-flag */
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen else if (++hdr->seen_messages_count == hdr->messages_count)
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen hdr->first_unseen_uid_lowwater = hdr->next_uid;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (((old_flags ^ new_flags) & MAIL_DELETED) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* different deleted-flag */
d482b35af87f5fd872bad007da0475813a401a49Timo Sirainen hdr->first_deleted_uid_lowwater = hdr->next_uid;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenmail_index_header_update_lowwaters(struct mail_index_header *hdr,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainenstatic void mail_index_sync_cache_expunge(struct mail_index_sync_map_ctx *ctx,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen if (mail_cache_lock(ctx->view->index->cache) <= 0)
2112c190034c937b4b1613c3689d8239adb6c310Timo Sirainen if (!MAIL_CACHE_IS_UNUSABLE(ctx->view->index->cache) &&
2112c190034c937b4b1613c3689d8239adb6c310Timo Sirainen (void)mail_cache_delete(ctx->view->index->cache, cache_offset);
53238473bf77147660aa6db9daa68a8a685e9381Timo Sirainenstatic int sync_expunge(const struct mail_transaction_expunge *e, void *context)
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* expunges have to be atomic. so we'll have to copy
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen the mapping, do the changes there and then finally
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen replace the whole index file. to avoid extra disk
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen I/O we copy the index into memory rather than to
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen temporary file */
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen if (mail_index_lookup_uid_range(view, e->uid1, e->uid2,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen hdr = buffer_get_modifyable_data(map->hdr_copy_buf, NULL);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_index_header_update_counts(hdr, rec->flags, 0);
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen mail_index_sync_cache_expunge(ctx, rec->cache_offset);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen /* @UNSAFE */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen memmove(MAIL_INDEX_MAP_IDX(map, seq1-1), MAIL_INDEX_MAP_IDX(map, seq2),
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen (map->records_count - seq2) * map->hdr->record_size);
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen buffer_set_used_size(map->buffer, map->records_count *
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen map->records = buffer_get_modifyable_data(map->buffer, NULL);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainenstatic int sync_append(const struct mail_index_record *rec, void *context)
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen hdr = buffer_get_modifyable_data(map->hdr_copy_buf, NULL);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen "Append with UID %u, but next_uid = %u",
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen i_assert(map->records_count * map->hdr->record_size ==
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen dest = buffer_append_space_unsafe(map->buffer,
ace3c14e47a5a865df8aeea2fabc993b609dd163Timo Sirainen map->records = buffer_get_modifyable_data(map->buffer, NULL);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen i_assert((map->records_count+1) * map->hdr->record_size <=
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen dest = MAIL_INDEX_MAP_IDX(map, map->records_count);
dd8de60250511cc729b67249e61dfc6b4debff11Timo Sirainen if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_index_header_update_counts(hdr, 0, rec->flags);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstatic int sync_flag_update(const struct mail_transaction_flag_update *u,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen if (mail_index_lookup_uid_range(view, u->uid1, u->uid2,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen hdr = buffer_get_modifyable_data(view->map->hdr_copy_buf, NULL);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if ((u->add_flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0)
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen if (u->add_keywords[i] != 0 ||
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen rec->flags = (rec->flags & flag_mask) | u->add_flags;
d8b77aef97e89f1ccc5cbdaef77be9052279e35fTimo Sirainen for (i = 0; i < INDEX_KEYWORDS_BYTE_COUNT; i++) {
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_index_header_update_counts(hdr, old_flags, rec->flags);
56f45b3f3ae20e5c933701f4657dda5ef1916855Timo Sirainenstatic int sync_cache_reset(const struct mail_transaction_cache_reset *u,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen hdr = buffer_get_modifyable_data(view->map->hdr_copy_buf, NULL);
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen MAIL_INDEX_MAP_IDX(view->map, i)->cache_offset = 0;
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstatic int sync_cache_update(const struct mail_transaction_cache_update *u,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen if (mail_index_lookup_uid_range(view, u->uid, u->uid, &seq, &seq) < 0)
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen /* already expunged */
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen if (rec->cache_offset != 0 && ctx->update_cache) {
a40d26f83af808a0ea1e212c001d682a96d870b0Timo Sirainen /* we'll need to link the old and new cache records */
f3a258b0930595dedaa4057d4104d99d4409a10eTimo Sirainen if ((ret = mail_cache_lock(view->index->cache)) <= 0)
f79a807865222dc8d5afd21667d2ace67f6c831bTimo Sirainen /* cache has been compressed, don't modify it */
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstatic int sync_header_update(const struct mail_transaction_header_update *u,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_sync_map_ctx *ctx = context;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen const struct mail_index_header *hdr = ctx->view->map->hdr;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen u->offset + u->size > hdr->base_header_size) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_transaction_log_view_set_corrupted(ctx->view->log_view,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen "Header update outside range: %u + %u > %u",
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen buffer_write(ctx->view->map->hdr_copy_buf, u->offset, u + 1, u->size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen ctx->view->map->hdr = ctx->view->map->hdr_copy_buf->data;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainenstatic int mail_index_ext_align_cmp(const void *p1, const void *p2)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen const struct mail_index_ext *const *e1 = p1, *const *e2 = p2;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen return (int)(*e2)->record_align - (int)(*e1)->record_align;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainensync_ext_reorder(struct mail_index_map *map, uint32_t ext_id, uint16_t old_size)
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen const void *src;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ext = buffer_get_modifyable_data(map->extensions, &size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* @UNSAFE */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen sorted = t_new(struct mail_index_ext *, size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (i = 0; i < size; i++) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen qsort(sorted, size, sizeof(struct mail_index_ext *),
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* we simply try to use the extensions with largest alignment
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen requirement first. FIXME: if the extension sizes don't match
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen alignmentation, this may not give the minimal layout. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (i = 0; i < size; i++) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* all done */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* we have to leave space here */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen i_assert(min_align > 1 && min_align < (uint16_t)-1);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* keep 32bit alignment */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen offset += sizeof(uint32_t) - (offset % sizeof(uint32_t));
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* create a new mapping without records. a bit kludgy. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen new_map = mail_index_map_to_memory(map, offset);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* now copy the records to new mapping */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (rec_idx = 0; rec_idx < old_records_count; rec_idx++) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen sizeof(struct mail_index_record));
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (i = 0; i < size; i++) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen src = CONST_PTR_OFFSET(src, map->hdr->record_size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen new_map->records = buffer_get_modifyable_data(new_map->buffer, NULL);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* update record offsets in headers */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen hdr = buffer_get_modifyable_data(new_map->hdr_copy_buf, NULL);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen for (i = 0; i < size; i++) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* kludgy jumping to get to the beginning of header. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MAIL_INDEX_HEADER_SIZE_ALIGN(sizeof(*ext_hdr) +
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ext_hdr->record_offset = ext[i].record_offset;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainensync_ext_resize(const struct mail_transaction_ext_intro *u, uint32_t ext_id,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen uint32_t offset, old_size, new_size, old_record_size;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen mail_transaction_log_view_set_corrupted(ctx->view->log_view,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen "Introduced existing extension with wrong id: %u != %u",
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ext = buffer_get_modifyable_data(map->extensions, NULL);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen old_size = MAIL_INDEX_HEADER_SIZE_ALIGN(ext->hdr_size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen new_size = MAIL_INDEX_HEADER_SIZE_ALIGN(u->hdr_size);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* header shrinked */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen buffer_delete(map->hdr_copy_buf, ext->hdr_offset + new_size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* header grown */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen hdr = buffer_get_modifyable_data(map->hdr_copy_buf, NULL);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* we need to modify ext header. do some kludgy jumping to
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen get to it. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MAIL_INDEX_HEADER_SIZE_ALIGN(sizeof(*ext_hdr) +
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen map = sync_ext_reorder(map, ext_id, old_record_size);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic int sync_ext_intro(const struct mail_transaction_ext_intro *u,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_sync_map_ctx *ctx = context;
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ext_id = mail_index_map_lookup_ext(map, name);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* exists already - are we resizing? */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen if (MAIL_INDEX_HEADER_SIZE_ALIGN(hdr_buf->used) != hdr_buf->used) {
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* we need to add padding between base header and extensions */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* register record offset initially using record size,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen sync_ext_reorder() will fix it. */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen hdr_offset = map->hdr_copy_buf->used + sizeof(ext_hdr) + strlen(name);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen hdr_offset = MAIL_INDEX_HEADER_SIZE_ALIGN(hdr_offset);
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen ext_id = mail_index_map_register_ext(ctx->view->index, map,
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* <ext_hdr> <name> [padding] [header data] */
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen buffer_append(hdr_buf, &ext_hdr, sizeof(ext_hdr));
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen /* header must begin and end in correct alignment */
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen MAIL_INDEX_HEADER_SIZE_ALIGN(hdr_buf->used) - hdr_buf->used +
bbf796c17f02538058d7559bfe96d677e5b55015Timo Sirainen hdr_offset + MAIL_INDEX_HEADER_SIZE_ALIGN(ext->hdr_size));
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen hdr = buffer_get_modifyable_data(hdr_buf, NULL);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_transaction_log_view_set_corrupted(ctx->view->log_view,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen "Introduced extension with invalid id: %u != %u",
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic int sync_ext_reset(const struct mail_transaction_ext_rec_header *u,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen u->ext_id >= map->extensions->used / sizeof(*ext)) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen "Extension reset for unknown id %u", u->ext_id);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen memset(buffer_get_space_unsafe(map->hdr_copy_buf, ext->hdr_offset,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen memset(PTR_OFFSET(rec, ext->record_offset), 0,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainenstatic int sync_ext_hdr_update(const struct mail_transaction_ext_hdr_update *u,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen struct mail_index_sync_map_ctx *ctx = context;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen u->ext_id >= map->extensions->used / sizeof(*ext)) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_transaction_log_view_set_corrupted(ctx->view->log_view,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen "Extension header update for unknown id %u", u->ext_id);
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen buffer_write(map->hdr_copy_buf, ext->hdr_offset + u->offset,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainensync_ext_rec_update(const struct mail_transaction_ext_rec_header *hdr,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen const struct mail_transaction_ext_rec_update *u,
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen struct mail_index_sync_map_ctx *ctx = context;
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen hdr->ext_id >= view->map->extensions->used / sizeof(*ext)) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_transaction_log_view_set_corrupted(view->log_view,
7797aa2479e99aeb71057b7a2584b2cb72e4d3f8Timo Sirainen "Extension update for unknown id %u", hdr->ext_id);
567e57b09a49bbb2a146b13f8617698eb56237feTimo Sirainen if (mail_index_lookup_uid_range(view, u->uid, u->uid, &seq, &seq) < 0)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstatic int mail_index_grow(struct mail_index *index, struct mail_index_map *map,
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen unsigned int count)
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen (map->records_count + count) * map->hdr->record_size;
690af4a90eaf8611c2573d34126bb7a852c50a44Timo Sirainen /* when we grow fast, do it exponentially */
7e94cf9d70ce9fdeccb7a85ff400b899e6386f36Timo Sirainen (map->records_count + count) * map->hdr->record_size;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (file_set_size(index->fd, (off_t)size) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return mail_index_set_syscall_error(index, "file_set_size()");
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen /* we only wish to grow the file, but mail_index_map() updates the
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen headers as well and may break our modified hdr_copy. so, take
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen a backup of it and put it back afterwards */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen memcpy(hdr_copy, map->hdr_copy_buf->data, hdr_copy_size);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen buffer_append(map->hdr_copy_buf, hdr_copy, hdr_copy_size);
d9e49848cb4a08f140892d76c2b54afabb9e675aTimo Sirainen map->records_count = map->hdr->messages_count;
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainenmail_index_update_day_headers(struct mail_index_header *hdr, uint32_t uid)
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen sizeof(hdr->day_first_uid) / sizeof(hdr->day_first_uid[0]);
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen /* get beginning of today */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen /* get number of days since last message */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen /* @UNSAFE: move days forward and fill the missing days with old
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen day_first_uid[0]. */
8aacc9e7c84f8376822823ec98c2f551d4919b2eTimo Sirainen hdr->day_first_uid[i] = hdr->day_first_uid[0];
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenint mail_index_sync_update_index(struct mail_index_sync_ctx *sync_ctx)
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen struct mail_index_view *view = sync_ctx->view;
7394389230750c45b105cdefb5850c81cae8cdc0Timo Sirainen memset(&sync_map_ctx, 0, sizeof(sync_map_ctx));
fec0e90484c5f2c9da9cdc62c0897408023d4c6eTimo Sirainen /* we'll have to update view->lock_id to avoid mail_index_view_lock()
fec0e90484c5f2c9da9cdc62c0897408023d4c6eTimo Sirainen trying to update the file later. */
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen if (mail_index_lock_exclusive(index, &view->lock_id) < 0)
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* NOTE: locking may change index->map so make sure the assignment is
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen after locking */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen tmphdr = buffer_get_modifyable_data(map->hdr_copy_buf, NULL);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen had_dirty = (tmphdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) != 0;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen tmphdr->flags &= ~MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen while ((ret = mail_transaction_log_view_next(view->log_view, &thdr,
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if ((thdr->type & MAIL_TRANSACTION_APPEND) != 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if (mail_transaction_map(view->map, thdr, data,
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen i_assert(map->records_count == map->hdr->messages_count);
ea546eaab672d441e180b7619d4750be813c08d8Timo Sirainen i_assert(view->messages_count == map->hdr->messages_count);
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainen mail_transaction_log_get_head(index->log, &seq, &offset);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen /* hdr pointer may have changed, update it */
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen tmphdr = buffer_get_modifyable_data(map->hdr_copy_buf, NULL);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen mail_index_update_day_headers(tmphdr, first_append_uid);
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen if ((tmphdr->flags & MAIL_INDEX_HDR_FLAG_HAVE_DIRTY) == 0 &&
b35f7104715edee0cfac6d46ab0b342033867eb7Timo Sirainen /* do we have dirty flags anymore? */
8e7da21696c9f8a6d5e601243fb6172ec85d47b2Timo Sirainen if ((rec->flags & MAIL_INDEX_MAIL_FLAG_DIRTY) != 0) {
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen tmphdr->flags |= MAIL_INDEX_HDR_FLAG_HAVE_DIRTY;
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen map->mmap_used_size = index->hdr->header_size +
5a07b37a9df398b5189c14872a600384208ab74bTimo Sirainen memcpy(map->mmap_base, tmphdr, tmphdr->header_size);
b2105c78f0fd58281317e6d777ded860f33153a3Timo Sirainen if (msync(map->mmap_base, map->mmap_used_size, MS_SYNC) < 0) {
5c1a8aee989af87bddefd71e2aa83aa2bd695155Timo Sirainen mail_index_set_syscall_error(index, "msync()");
e06c0b65c16ccce69bbee009ead14d7d3d17a256Timo Sirainenstruct mail_transaction_map_functions mail_index_map_sync_funcs = {