mail-cache-sync-update.c revision 0f20dd043770d8c4460e5cfc2e8741e58c949ab6
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale/* Copyright (C) 2004 Timo Sirainen */
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller#include "lib.h"
7bde6e1907fc17b0083a6bcfad10bb74be6e4bcdTim Reddehase#include "file-cache.h"
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller#include "mail-cache-private.h"
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller#include "mail-index-view-private.h"
76e062333eb08ffc0c22578cc86ffc970c321fecTim Reddehase#include "mail-index-sync-private.h"
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehasestruct mail_cache_sync_context {
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase unsigned int locked:1;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase unsigned int lock_failed:1;
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller};
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning muellerstatic void mail_cache_handler_deinit(struct mail_index_sync_map_ctx *sync_ctx,
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller struct mail_cache_sync_context *ctx)
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger{
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger if (ctx == NULL)
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger return;
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase if (ctx->locked)
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller (void)mail_cache_unlock(sync_ctx->view->index->cache);
2fb61b27ca20bf21f93dd0866c01e58b429baeb5Eileen Bolloff i_free(ctx);
2fb61b27ca20bf21f93dd0866c01e58b429baeb5Eileen Bolloff}
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehasestatic int mail_cache_handler_init(struct mail_cache_sync_context **ctx_r,
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller struct mail_cache *cache)
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger{
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger struct mail_cache_sync_context *ctx = *ctx_r;
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger int ret;
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller
a837d007b255d7a6cca7994e1e555aba95ce41cchenning mueller if (ctx == NULL)
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller ctx = *ctx_r = i_new(struct mail_cache_sync_context, 1);
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase if (ctx->locked)
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase return 1;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase if (ctx->lock_failed)
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase return 0;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase if (!ctx->locked) {
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase if ((ret = mail_cache_lock(cache)) <= 0) {
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase ctx->lock_failed = TRUE;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase return ret;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase }
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase ctx->locked = TRUE;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase }
083f87068ffcf24df8b0154bfbca4ca5027f8ecehenning mueller return 1;
083f87068ffcf24df8b0154bfbca4ca5027f8ecehenning mueller}
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Valestatic int get_cache_file_seq(struct mail_index_view *view,
ee5342a8882c2fc7631fcffb5497e6597747887cTim Reddehase uint32_t *cache_file_seq_r)
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale{
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase const struct mail_index_ext *ext;
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase ext = mail_index_view_get_ext(view, view->index->cache->ext_id);
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale if (ext == NULL)
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase return 0;
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase *cache_file_seq_r = ext->reset_id;
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale return 1;
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale}
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehaseint mail_cache_expunge_handler(struct mail_index_sync_map_ctx *sync_ctx,
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase uint32_t seq __attr_unused__, const void *data,
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase void **sync_context, void *context)
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase{
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase struct mail_cache *cache = context;
71fdc30cc6e637d99cacb455537e7b8fbfe77395henning mueller struct mail_cache_sync_context *ctx = *sync_context;
71fdc30cc6e637d99cacb455537e7b8fbfe77395henning mueller const uint32_t *cache_offset = data;
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale uint32_t cache_file_seq;
d1860f0434d6460259d04f8952e55df38fe517f7Tim Reddehase int ret;
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale
40c5626383ebd5e8cf11a636f864023a2aafcd6bDaniel Couto Vale if (data == NULL) {
a837d007b255d7a6cca7994e1e555aba95ce41cchenning mueller mail_cache_handler_deinit(sync_ctx, ctx);
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger *sync_context = NULL;
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger return 0;
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller }
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase if (*cache_offset == 0)
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase return 0;
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase if (MAIL_CACHE_IS_UNUSABLE(cache))
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase return 0;
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase ret = mail_cache_handler_init(&ctx, cache);
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase *sync_context = ctx;
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase if (ret <= 0)
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase return ret;
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase if (!get_cache_file_seq(sync_ctx->view, &cache_file_seq))
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase return 0;
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase if (!MAIL_CACHE_IS_UNUSABLE(cache) &&
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase cache_file_seq == cache->hdr->file_seq)
75c2a995e5c564f96cf5559145e59f89d6435ee1Tim Reddehase (void)mail_cache_delete(cache, *cache_offset);
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller return 0;
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller}
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehaseint mail_cache_sync_handler(struct mail_index_sync_map_ctx *sync_ctx,
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase uint32_t seq __attr_unused__,
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase void *old_data, const void *new_data,
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase void **context)
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase{
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase struct mail_index_view *view = sync_ctx->view;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase struct mail_cache *cache = view->index->cache;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase struct mail_cache_sync_context *ctx = *context;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase const uint32_t *old_cache_offset = old_data;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase const uint32_t *new_cache_offset = new_data;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase uint32_t cache_file_seq, cur_seq, tail_seq;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase uoff_t cur_offset, tail_offset;
2977875e15fdb6d84be990579c61cda0b6cbb5d0Tim Reddehase int ret;
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase
435547b6b5df0f76cd04b09532341b07d0defeb1Tim Reddehase if (new_cache_offset == NULL) {
609a4ff9a0e4cb89a9f529703c81554fe9c34ff6Tim Reddehase mail_cache_handler_deinit(sync_ctx, ctx);
609a4ff9a0e4cb89a9f529703c81554fe9c34ff6Tim Reddehase *context = NULL;
609a4ff9a0e4cb89a9f529703c81554fe9c34ff6Tim Reddehase return 1;
609a4ff9a0e4cb89a9f529703c81554fe9c34ff6Tim Reddehase }
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase if (MAIL_CACHE_IS_UNUSABLE(cache))
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase return 1;
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase if (cache->file_cache != NULL) {
609a4ff9a0e4cb89a9f529703c81554fe9c34ff6Tim Reddehase file_cache_invalidate(cache->file_cache, *new_cache_offset,
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase (uoff_t)-1);
3856b7bdf70cec553e0ca01ca823c7fc555a06f0Tim Reddehase }
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase
609a4ff9a0e4cb89a9f529703c81554fe9c34ff6Tim Reddehase if (*old_cache_offset == 0 || *old_cache_offset == *new_cache_offset ||
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase sync_ctx->type == MAIL_INDEX_SYNC_HANDLER_VIEW)
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase return 1;
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase mail_transaction_log_view_get_prev_pos(view->log_view,
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase &cur_seq, &cur_offset);
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase mail_transaction_log_get_mailbox_sync_pos(view->index->log,
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase &tail_seq, &tail_offset);
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase if (LOG_IS_BEFORE(cur_seq, cur_offset, tail_seq, tail_offset)) {
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase /* already been linked */
a8ab4146c3238374bdd13a36b12d665cde57e078Tim Reddehase return 1;
58721b9d3a8cd6a624269ddf507f80af4417c9bdhenning mueller }
519002bc41b20a069be1c669660e702f9bd4a593Eugen Kuksa
705933deb08bc4269e8c08d50143af3cb5c1c670henning mueller /* we'll need to link the old and new cache records */
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornberger ret = mail_cache_handler_init(&ctx, cache);
881c5d2df3b2375b1ed2093781643873e424fe2cTim Reddehase *context = ctx;
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornberger if (ret <= 0)
ac2169141f0b549fc8917a4b1d778f4ba3cab0bfJulian Kornberger return ret < 0 ? -1 : 1;
ac2169141f0b549fc8917a4b1d778f4ba3cab0bfJulian Kornberger
aa056a2e5efb6505701a4e4a31bf2f7e71ff1738henning mueller if (!get_cache_file_seq(view, &cache_file_seq))
ac2169141f0b549fc8917a4b1d778f4ba3cab0bfJulian Kornberger return 1;
705933deb08bc4269e8c08d50143af3cb5c1c670henning mueller
519002bc41b20a069be1c669660e702f9bd4a593Eugen Kuksa if (cache_file_seq != cache->hdr->file_seq) {
519002bc41b20a069be1c669660e702f9bd4a593Eugen Kuksa /* cache has been compressed, don't modify it */
aa056a2e5efb6505701a4e4a31bf2f7e71ff1738henning mueller return 1;
aa056a2e5efb6505701a4e4a31bf2f7e71ff1738henning mueller }
aa056a2e5efb6505701a4e4a31bf2f7e71ff1738henning mueller
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger if (mail_cache_link(cache, *old_cache_offset, *new_cache_offset) < 0)
705933deb08bc4269e8c08d50143af3cb5c1c670henning mueller return -1;
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornberger
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornberger return 1;
705933deb08bc4269e8c08d50143af3cb5c1c670henning mueller}
b5bf21df9d1d61069e6dc9e13569543d0b868bc8Daniel Couto Vale
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornbergervoid mail_cache_sync_lost_handler(struct mail_index *index)
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornberger{
2e7a48951591a6eeda9a3ab4e14cd13012cb43eaJulian Kornberger file_cache_invalidate(index->cache->file_cache, 0, (uoff_t)-1);
aa056a2e5efb6505701a4e4a31bf2f7e71ff1738henning mueller}
a274d776b3371051dcdd74b598182ce113ca5135Julian Kornberger