mail-cache-sync-update.c revision 45312f52ff3a3d4c137447be4c7556500c2f8bf2
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek/* Copyright (c) 2004-2009 Dovecot authors, see the included COPYING file */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "lib.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "file-cache.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "mail-cache-private.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "mail-index-view-private.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek#include "mail-index-sync-private.h"
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekstruct mail_cache_sync_context {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uoff_t invalidate_highwater;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek unsigned int locked:1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek unsigned int lock_failed:1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek unsigned int nfs_read_cache_flushed:1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek};
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekstatic void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache_sync_context *ctx)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ctx == NULL)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ctx->locked)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek (void)mail_cache_unlock(sync_ctx->view->index->cache);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek i_free(ctx);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekstatic struct mail_cache_sync_context *mail_cache_handler_init(void **context)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache_sync_context *ctx;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (*context != NULL)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx = *context;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek else {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *context = i_new(struct mail_cache_sync_context, 1);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx = *context;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx->invalidate_highwater = (uoff_t)-1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ctx;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekstatic int mail_cache_handler_lock(struct mail_cache_sync_context *ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache *cache)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ctx->locked)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return MAIL_CACHE_IS_UNUSABLE(cache) ? 0 : 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ctx->lock_failed)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 0;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!ctx->locked) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if ((ret = mail_cache_lock(cache, TRUE)) <= 0) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx->lock_failed = TRUE;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx->locked = TRUE;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekstatic bool get_cache_file_seq(struct mail_index_view *view,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uint32_t *cache_file_seq_r)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const struct mail_index_ext *ext;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ext = mail_index_view_get_ext(view, view->index->cache->ext_id);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ext == NULL)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return FALSE;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *cache_file_seq_r = ext->reset_id;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return TRUE;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uint32_t seq ATTR_UNUSED, const void *data,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek void **sync_context, void *context)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache *cache = context;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache_sync_context *ctx = *sync_context;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const uint32_t *cache_offset = data;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uint32_t cache_file_seq;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (data == NULL) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek mail_cache_handler_deinit(sync_ctx, ctx);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *sync_context = NULL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 0;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (*cache_offset == 0)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 0;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx = mail_cache_handler_init(sync_context);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = mail_cache_handler_lock(ctx, cache);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret <= 0)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!get_cache_file_seq(sync_ctx->view, &cache_file_seq))
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 0;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!MAIL_CACHE_IS_UNUSABLE(cache) &&
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek cache_file_seq == cache->hdr->file_seq)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek (void)mail_cache_delete(cache, *cache_offset);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 0;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekint mail_cache_sync_handler(struct mail_index_sync_map_ctx *sync_ctx,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uint32_t seq ATTR_UNUSED,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek void *old_data, const void *new_data,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek void **context)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_index_view *view = sync_ctx->view;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache *cache = view->index->cache;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache_sync_context *ctx = *context;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const uint32_t *old_cache_offset = old_data;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek const uint32_t *new_cache_offset = new_data;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uint32_t cache_file_seq, cur_seq, tail_seq;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek uoff_t cur_offset, tail_offset;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek int ret;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (new_cache_offset == NULL) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek mail_cache_handler_deinit(sync_ctx, ctx);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *context = NULL;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx = mail_cache_handler_init(context);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (cache->file_cache != NULL && !MAIL_CACHE_IS_UNUSABLE(cache)) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* flush read cache only once per sync */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!ctx->nfs_read_cache_flushed && cache->index->nfs_flush) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx->nfs_read_cache_flushed = TRUE;
234958be042980242fff6da936af674da877c5efSimo Sorce mail_index_flush_read_cache(cache->index,
234958be042980242fff6da936af674da877c5efSimo Sorce cache->filepath, cache->fd,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek cache->locked);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* don't invalidate anything that's already been invalidated
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek within this sync. */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (*new_cache_offset < ctx->invalidate_highwater) {
234958be042980242fff6da936af674da877c5efSimo Sorce file_cache_invalidate(cache->file_cache,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *new_cache_offset,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx->invalidate_highwater -
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek *new_cache_offset);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ctx->invalidate_highwater = *new_cache_offset;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (*old_cache_offset == 0 || *old_cache_offset == *new_cache_offset ||
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek sync_ctx->type == MAIL_INDEX_SYNC_HANDLER_VIEW)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek mail_transaction_log_view_get_prev_pos(view->log_view,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek &cur_seq, &cur_offset);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek mail_transaction_log_get_mailbox_sync_pos(view->index->log,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek &tail_seq, &tail_offset);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (LOG_IS_BEFORE(cur_seq, cur_offset, tail_seq, tail_offset)) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* already been linked */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* we'll need to link the old and new cache records */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek ret = mail_cache_handler_lock(ctx, cache);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (ret <= 0)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return ret < 0 ? -1 : 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta if (!get_cache_file_seq(view, &cache_file_seq))
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (cache_file_seq != cache->hdr->file_seq) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek /* cache has been compressed, don't modify it */
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (mail_cache_link(cache, *old_cache_offset, *new_cache_offset) < 0)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return -1;
965428847850f1b154130e249f2d942c6065e88dSimo Sorce
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek return 1;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek}
2d6836a90bd326391782a5753f70e8ba666b5defJan Cholasta
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidekvoid mail_cache_sync_lost_handler(struct mail_index *index)
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek{
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek struct mail_cache *cache = index->cache;
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek if (!MAIL_CACHE_IS_UNUSABLE(cache)) {
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek mail_index_flush_read_cache(cache->index, cache->filepath,
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek cache->fd, cache->locked);
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek }
965428847850f1b154130e249f2d942c6065e88dSimo Sorce file_cache_invalidate(cache->file_cache, 0, (uoff_t)-1);
965428847850f1b154130e249f2d942c6065e88dSimo Sorce}
25f8fac2489fd209d603acb2b494f7c72968e9bbMichal Zidek