mail-index-view-sync.c revision 7888a9d2008eab9985096c46e1da9ee985c22a2a
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Copyright (C) 2003-2004 Timo Sirainen */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenview_sync_get_expunges(struct mail_index_view *view, buffer_t **expunges_r)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const struct mail_transaction_expunge *exp, *end;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* with mask 0 we don't get anything, we'll just read the expunges
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while seeking to end */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_next(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen expunges = mail_transaction_log_view_get_expunges(view->log_view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *expunges_r = buffer_create_dynamic(default_pool, size, (size_t)-1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(*expunges_r, &exp->seq1, sizeof(exp->seq1));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(*expunges_r, &exp->seq2, sizeof(exp->seq2));
7888a9d2008eab9985096c46e1da9ee985c22a2aTimo Sirainen mail_transaction_log_view_unset(view->log_view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_begin(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* We must sync flags as long as view is mmap()ed, as the flags may
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen have already changed under us. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen i_assert((sync_mask & MAIL_INDEX_SYNC_TYPE_FLAGS) != 0);
31ddc75584c5cde53d2e78a737587f2e7fdcb0d2Timo Sirainen if (mail_index_view_lock_head(view, TRUE) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if ((sync_mask & MAIL_INDEX_SYNC_TYPE_EXPUNGE) != 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* get list of all expunges first */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_sync_get_expunges(view, &expunges) < 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mask = mail_transaction_type_mask_get(sync_mask);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (mail_transaction_log_view_set(view->log_view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ctx = i_new(struct mail_index_view_sync_ctx, 1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int view_is_transaction_synced(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data = buffer_get_data(view->log_syncs, &size);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *((const uint32_t *)(data + sizeof(uoff_t))) == seq)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int sync_expunge(const struct mail_transaction_expunge *e, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_header_update_counts(&map->hdr_copy,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (e->seq1-1) * sizeof(struct mail_index_record),
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map->records = buffer_get_modifyable_data(map->buffer, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int sync_append(const struct mail_index_record *rec, void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(map->buffer, rec, sizeof(*rec));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map->records = buffer_get_modifyable_data(map->buffer, NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_header_update_counts(&map->hdr_copy, 0, rec->flags);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_header_update_lowwaters(&map->hdr_copy, rec);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int sync_flag_update(const struct mail_transaction_flag_update *u,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, idx;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen rec->flags = (rec->flags & ~u->remove_flags) | u->add_flags;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen for (i = 0; i < INDEX_CUSTOM_FLAGS_BYTE_COUNT; i++) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_header_update_counts(&map->hdr_copy, old_flags,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_header_update_lowwaters(&map->hdr_copy, rec);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int sync_cache_update(const struct mail_transaction_cache_update *u,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen map->records[u->seq-1].cache_offset = u->cache_offset;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mail_index_view_sync_map(struct mail_index_view_sync_ctx *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen static struct mail_transaction_map_functions map_funcs = {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen sync_expunge, sync_append, sync_flag_update, sync_cache_update
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return mail_transaction_map(ctx->hdr, ctx->data,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic int mail_index_view_sync_next_trans(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_transaction_log_view *log_view = ctx->view->log_view;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mail_transaction_log_view_next(log_view, &ctx->hdr, &ctx->data,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_transaction_log_view_get_prev_pos(log_view, seq_r, offset_r);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* skip flag changes that we committed ourself or have already synced */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (view_is_transaction_synced(view, *seq_r, *offset_r))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->sync_mask != MAIL_INDEX_SYNC_MASK_ALL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_index_view_sync_next(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (ctx->hdr == NULL || ctx->data_offset == ctx->hdr->size) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ret = mail_index_view_sync_next_trans(ctx, &seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } while (ret == 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_view_add_synced_transaction(view, seq,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!mail_index_sync_get_rec(view, sync_rec, ctx->hdr, ctx->data,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmail_index_view_sync_get_expunges(struct mail_index_view_sync_ctx *ctx,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_sync_end(struct mail_index_view_sync_ctx *ctx)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* we didn't sync everything */
7888a9d2008eab9985096c46e1da9ee985c22a2aTimo Sirainen mail_transaction_log_view_unset(view->log_view);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid mail_index_view_add_synced_transaction(struct mail_index_view *view,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen view->log_syncs = buffer_create_dynamic(default_pool,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen buffer_append(view->log_syncs, &log_file_offset,