index-transaction.c revision ba8b5d510a75b74afa967ce43dd79d6a9d2558b3
2e37d45867d081db150ab78dad303b9077aea24fTimo Sirainen/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "lib.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "array.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "index-storage.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen#include "index-mail.h"
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void index_transaction_free(struct index_transaction_context *t)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_cache_view_close(t->cache_view);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen mail_index_view_close(&t->mailbox_ctx.view);
7a7d2aa11e46195e2d92d6c337d7e78052a5ce67Timo Sirainen array_free(&t->mailbox_ctx.module_contexts);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_free(t);
c115c742f730e312d6b6ab5064595cd0d8b4e26eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic int
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenindex_transaction_index_commit(struct mail_index_transaction *index_trans,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail_index_transaction_commit_result *result_r)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct index_transaction_context *it =
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen MAIL_STORAGE_CONTEXT(index_trans);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_transaction_context *t = &it->mailbox_ctx;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(t->box);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen int ret = 0;
499fec3443374cc89fb8c83b8027c1614097d7a3Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen if (t->save_ctx != NULL) {
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen if (ibox->save_commit_pre(t->save_ctx) < 0) {
f5a7396b31762a1f876517e13ce9065820139f7cTimo Sirainen t->save_ctx = NULL;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen ret = -1;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen i_assert(it->mail_ref_count == 0);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (ret < 0)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen it->super.rollback(index_trans);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen else {
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (it->super.commit(index_trans, result_r) < 0) {
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen mail_storage_set_index_error(t->box);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen ret = -1;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen }
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen if (t->save_ctx != NULL)
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen ibox->save_commit_post(t->save_ctx, result_r);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen index_transaction_free(it);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return ret;
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen}
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainenstatic void index_transaction_index_rollback(struct mail_index_transaction *t)
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen{
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen struct index_transaction_context *it = MAIL_STORAGE_CONTEXT(t);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen struct index_mailbox_context *ibox =
11352dc3e4b29f3d2763c82f8ea4f99e8daf4fa3Timo Sirainen INDEX_STORAGE_CONTEXT(it->mailbox_ctx.box);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen if (it->mailbox_ctx.save_ctx != NULL)
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen ibox->save_rollback(it->mailbox_ctx.save_ctx);
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen
942302b0247403645394d848b3c620ead262a2a5Timo Sirainen it->super.rollback(t);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen index_transaction_free(it);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenvoid index_transaction_init(struct index_transaction_context *it,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox *box,
cd8507179823de33d6e8242e10dbc15d136245b5Timo Sirainen enum mailbox_transaction_flags flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox_transaction_context *t = &it->mailbox_ctx;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum mail_index_transaction_flags trans_flags;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen i_assert(box->opened);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen trans_flags = MAIL_INDEX_TRANSACTION_FLAG_AVOID_FLAG_UPDATES;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if ((flags & MAILBOX_TRANSACTION_FLAG_HIDE) != 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_HIDE;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if ((flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen if ((flags & MAILBOX_TRANSACTION_FLAG_REFRESH) != 0)
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen (void)mail_index_refresh(box->index);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen t->box = box;
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen t->itrans = mail_index_transaction_begin(box->view, trans_flags);
2615df45a8027948a474abe5e817b34b0499c171Timo Sirainen t->view = mail_index_transaction_open_updated_view(t->itrans);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen array_create(&t->module_contexts, default_pool,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen sizeof(void *), 5);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen it->cache_view = mail_cache_view_open(box->cache, t->view);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen it->cache_trans = mail_cache_get_transaction(it->cache_view, t->itrans);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* set up after mail_cache_get_transaction(), so that we'll still
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen have the cache_trans available in _index_commit() */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen it->super = t->itrans->v;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen t->itrans->v.commit = index_transaction_index_commit;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen t->itrans->v.rollback = index_transaction_index_rollback;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen MODULE_CONTEXT_SET(t->itrans, mail_storage_mail_index_module, it);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstruct mailbox_transaction_context *
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenindex_transaction_begin(struct mailbox *box,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen enum mailbox_transaction_flags flags)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct index_transaction_context *it;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen it = i_new(struct index_transaction_context, 1);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen index_transaction_init(it, box, flags);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen return &it->mailbox_ctx;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen}
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenint index_transaction_commit(struct mailbox_transaction_context *t,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail_transaction_commit_changes *changes_r)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen{
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mailbox *box = t->box;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct mail_index_transaction *itrans = t->itrans;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen struct mail_index_transaction_commit_result result;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen int ret;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen memset(changes_r, 0, sizeof(*changes_r));
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen changes_r->pool = pool_alloconly_create(MEMPOOL_GROWING
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen "transaction changes", 512);
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen p_array_init(&changes_r->saved_uids, changes_r->pool, 32);
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen t->changes = changes_r;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen ret = mail_index_transaction_commit_full(&itrans, &result);
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen t = NULL;
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen if (ret < 0 && mail_index_is_deleted(box->index))
c93ff0433cc3d348116f75a64f9988fedb86fd18Timo Sirainen mailbox_set_deleted(box);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen changes_r->ignored_uid_changes = result.ignored_uid_changes;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen changes_r->ignored_modseq_changes = result.ignored_modseq_changes;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen return ret;
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen
11352dc3e4b29f3d2763c82f8ea4f99e8daf4fa3Timo Sirainenvoid index_transaction_rollback(struct mailbox_transaction_context *t)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen struct mail_index_transaction *itrans = t->itrans;
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen mail_index_transaction_rollback(&itrans);
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen}
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainenvoid index_transaction_set_max_modseq(struct mailbox_transaction_context *t,
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen uint64_t max_modseq,
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen ARRAY_TYPE(seq_range) *seqs)
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen{
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen mail_index_transaction_set_max_modseq(t->itrans, max_modseq, seqs);
132487b9a47c2eb6fc80cfa2b0aaf82c6dc3af56Timo Sirainen}
755aea84bbe2b15ed7fe991f6462a93333ff571fTimo Sirainen