mail-cache-sync-update.c revision f23298fea47eecbeded985ee2537a34c4c4ef56b
3bce8af465e45b9b06f106f6c7f28b2a4b6cca43Timo Sirainen/* Copyright (C) 2004 Timo Sirainen */
3bce8af465e45b9b06f106f6c7f28b2a4b6cca43Timo Sirainen
3bce8af465e45b9b06f106f6c7f28b2a4b6cca43Timo Sirainen#include "lib.h"
79789a60ce068d7abcb9a91b846334047441295dTimo Sirainen#include "file-cache.h"
95ba9d0ffaa6963b3e3838a353e7bdec45526851Timo Sirainen#include "mail-cache-private.h"
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen#include "mail-index-view-private.h"
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen#include "mail-index-sync-private.h"
9f86dab529923d0b73f8f42be23a01651c5212c3Timo Sirainen
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainenstruct mail_cache_sync_context {
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen unsigned int locked:1;
95ba9d0ffaa6963b3e3838a353e7bdec45526851Timo Sirainen unsigned int lock_failed:1;
95ba9d0ffaa6963b3e3838a353e7bdec45526851Timo Sirainen};
95ba9d0ffaa6963b3e3838a353e7bdec45526851Timo Sirainen
9f86dab529923d0b73f8f42be23a01651c5212c3Timo Sirainenstatic void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
95ba9d0ffaa6963b3e3838a353e7bdec45526851Timo Sirainen struct mail_cache_sync_context *ctx)
95ba9d0ffaa6963b3e3838a353e7bdec45526851Timo Sirainen{
35efafe673ad2917b234bc8747707093cb2f0746Timo Sirainen if (ctx == NULL)
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen return;
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen
a8bfc59dc5f87930d419ef5479368cc84e42fceeTimo Sirainen if (ctx->locked)
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen mail_cache_unlock(sync_ctx->view->index->cache);
3210ef33348492656c4eec6c3ee72dea4c7302c1Timo Sirainen i_free(ctx);
935a507ad94d7725eb3f1dae4d1eac23d900e6a9Timo Sirainen}
650f4afac9bd8cfa889cbb62e39b7490f5a628fbTimo Sirainen
650f4afac9bd8cfa889cbb62e39b7490f5a628fbTimo Sirainenstatic int mail_cache_handler_init(struct mail_cache_sync_context **ctx_r,
650f4afac9bd8cfa889cbb62e39b7490f5a628fbTimo Sirainen struct mail_cache *cache)
650f4afac9bd8cfa889cbb62e39b7490f5a628fbTimo Sirainen{
650f4afac9bd8cfa889cbb62e39b7490f5a628fbTimo Sirainen struct mail_cache_sync_context *ctx = *ctx_r;
int ret;
if (ctx == NULL)
ctx = *ctx_r = i_new(struct mail_cache_sync_context, 1);
if (ctx->locked)
return 1;
if (ctx->lock_failed)
return 0;
if (!ctx->locked) {
if ((ret = mail_cache_lock(cache)) <= 0) {
ctx->lock_failed = TRUE;
return ret;
}
ctx->locked = TRUE;
}
return 1;
}
static int get_cache_file_seq(struct mail_index_view *view,
uint32_t *cache_file_seq_r)
{
const struct mail_index_ext *ext;
ext = mail_index_view_get_ext(view, view->index->cache->ext_id);
if (ext == NULL)
return 0;
*cache_file_seq_r = ext->reset_id;
return 1;
}
int mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx,
uint32_t seq __attr_unused__,
const void *data, void **context)
{
struct mail_index_view *view = sync_ctx->view;
struct mail_cache_sync_context *ctx = *context;
struct mail_cache *cache = view->index->cache;
const uint32_t *cache_offset = data;
uint32_t cache_file_seq;
int ret;
if (data == NULL) {
mail_cache_handler_deinit(sync_ctx, ctx);
*context = NULL;
return 1;
}
if (*cache_offset == 0)
return 1;
if (MAIL_CACHE_IS_UNUSABLE(cache))
return 1;
ret = mail_cache_handler_init(&ctx, cache);
*context = ctx;
if (ret <= 0)
return ret < 0 ? -1 : 1;
if (!get_cache_file_seq(view, &cache_file_seq))
return 1;
if (!MAIL_CACHE_IS_UNUSABLE(cache) &&
cache_file_seq != cache->hdr->file_seq)
(void)mail_cache_delete(cache, *cache_offset);
return 1;
}
int mail_cache_sync_handler(struct mail_index_sync_map_ctx *sync_ctx,
uint32_t seq __attr_unused__,
void *old_data, const void *new_data,
void **context)
{
struct mail_index_view *view = sync_ctx->view;
struct mail_cache *cache = view->index->cache;
struct mail_cache_sync_context *ctx = *context;
const uint32_t *old_cache_offset = old_data;
const uint32_t *new_cache_offset = new_data;
uint32_t cache_file_seq;
int ret;
if (new_cache_offset == NULL) {
mail_cache_handler_deinit(sync_ctx, ctx);
*context = NULL;
return 1;
}
if (MAIL_CACHE_IS_UNUSABLE(cache))
return 1;
if (cache->file_cache != NULL) {
file_cache_invalidate(cache->file_cache, *new_cache_offset,
(uoff_t)-1);
}
if (*old_cache_offset == 0 ||
sync_ctx->type != MAIL_INDEX_SYNC_HANDLER_INDEX)
return 1;
/* we'll need to link the old and new cache records */
ret = mail_cache_handler_init(&ctx, cache);
*context = ctx;
if (ret <= 0)
return ret < 0 ? -1 : 1;
if (!get_cache_file_seq(view, &cache_file_seq))
return 1;
if (cache_file_seq != cache->hdr->file_seq) {
/* cache has been compressed, don't modify it */
return 1;
}
if (mail_cache_link(cache, *old_cache_offset, *new_cache_offset) < 0)
return -1;
return 1;
}
void mail_cache_sync_lost_handler(struct mail_index *index)
{
file_cache_invalidate(index->cache->file_cache, 0, (uoff_t)-1);
}