cydir-mail.c \
cydir-save.c \
cydir-sync.c \
- cydir-storage.c \
- cydir-transaction.c
+ cydir-storage.c
headers = \
cydir-storage.h \
}
struct mail_save_context *
-cydir_save_alloc(struct mailbox_transaction_context *_t)
+cydir_save_alloc(struct mailbox_transaction_context *t)
{
- struct cydir_transaction_context *t =
- (struct cydir_transaction_context *)_t;
- struct cydir_mailbox *mbox = (struct cydir_mailbox *)_t->box;
- struct cydir_save_context *ctx = t->save_ctx;
-
- i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
-
- if (t->save_ctx != NULL)
- return &t->save_ctx->ctx;
-
- ctx = t->save_ctx = i_new(struct cydir_save_context, 1);
- ctx->ctx.transaction = &t->ictx.mailbox_ctx;
- ctx->mbox = mbox;
- ctx->trans = t->ictx.trans;
- ctx->tmp_basename = cydir_generate_tmp_filename();
- return &ctx->ctx;
+ struct index_transaction_context *it =
+ (struct index_transaction_context *)t;
+ struct cydir_mailbox *mbox = (struct cydir_mailbox *)t->box;
+ struct cydir_save_context *ctx =
+ (struct cydir_save_context *)t->save_ctx;
+
+ i_assert((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
+
+ if (t->save_ctx == NULL) {
+ ctx = i_new(struct cydir_save_context, 1);
+ ctx->ctx.transaction = t;
+ ctx->mbox = mbox;
+ ctx->trans = it->trans;
+ ctx->tmp_basename = cydir_generate_tmp_filename();
+ t->save_ctx = &ctx->ctx;
+ }
+ return t->save_ctx;
}
int cydir_save_begin(struct mail_save_context *_ctx, struct istream *input)
(void)cydir_save_finish(_ctx);
}
-int cydir_transaction_save_commit_pre(struct cydir_save_context *ctx)
+int cydir_transaction_save_commit_pre(struct mail_save_context *_ctx)
{
- struct mailbox_transaction_context *_t = ctx->ctx.transaction;
+ struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
+ struct mailbox_transaction_context *_t = _ctx->transaction;
const struct mail_index_header *hdr;
struct seq_range_iter iter;
uint32_t uid;
if (cydir_sync_begin(ctx->mbox, &ctx->sync_ctx, TRUE) < 0) {
ctx->failed = TRUE;
- cydir_transaction_save_rollback(ctx);
+ cydir_transaction_save_rollback(_ctx);
return -1;
}
"rename(%s, %s) failed: %m",
str_c(src_path), str_c(dest_path));
ctx->failed = TRUE;
- cydir_transaction_save_rollback(ctx);
+ cydir_transaction_save_rollback(_ctx);
return -1;
}
}
return 0;
}
-void cydir_transaction_save_commit_post(struct cydir_save_context *ctx)
+void cydir_transaction_save_commit_post(struct mail_save_context *_ctx)
{
- ctx->ctx.transaction = NULL; /* transaction is already freed */
+ struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
+
+ _ctx->transaction = NULL; /* transaction is already freed */
(void)cydir_sync_finish(&ctx->sync_ctx, TRUE);
- cydir_transaction_save_rollback(ctx);
+ cydir_transaction_save_rollback(_ctx);
}
-void cydir_transaction_save_rollback(struct cydir_save_context *ctx)
+void cydir_transaction_save_rollback(struct mail_save_context *_ctx)
{
+ struct cydir_save_context *ctx = (struct cydir_save_context *)_ctx;
+
if (!ctx->finished)
cydir_save_cancel(&ctx->ctx);
mbox->ibox.box.list = list;
mbox->ibox.mail_vfuncs = &cydir_mail_vfuncs;
+ mbox->ibox.save_commit_pre = cydir_transaction_save_commit_pre;
+ mbox->ibox.save_commit_post = cydir_transaction_save_commit_post;
+ mbox->ibox.save_rollback = cydir_transaction_save_rollback;
+
index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
CYDIR_INDEX_PREFIX);
mail_index_set_fsync_types(mbox->ibox.index,
return ret;
}
-static void cydir_class_init(void)
-{
- cydir_transaction_class_init();
-}
-
-static void cydir_class_deinit(void)
-{
- cydir_transaction_class_deinit();
-}
-
static void cydir_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
struct mailbox_list *list)
{
{
NULL,
- cydir_class_init,
- cydir_class_deinit,
cydir_storage_alloc,
NULL,
index_storage_destroy,
struct cydir_storage *storage;
};
-struct cydir_transaction_context {
- struct index_transaction_context ictx;
- union mail_index_transaction_module_context module_ctx;
-
- uint32_t first_saved_mail_seq;
- struct cydir_save_context *save_ctx;
-};
-
extern struct mail_vfuncs cydir_mail_vfuncs;
-void cydir_transaction_class_init(void);
-void cydir_transaction_class_deinit(void);
-
struct mail_save_context *
cydir_save_alloc(struct mailbox_transaction_context *_t);
int cydir_save_begin(struct mail_save_context *ctx, struct istream *input);
int cydir_save_finish(struct mail_save_context *ctx);
void cydir_save_cancel(struct mail_save_context *ctx);
-int cydir_transaction_save_commit_pre(struct cydir_save_context *ctx);
-void cydir_transaction_save_commit_post(struct cydir_save_context *ctx);
-void cydir_transaction_save_rollback(struct cydir_save_context *ctx);
+int cydir_transaction_save_commit_pre(struct mail_save_context *ctx);
+void cydir_transaction_save_commit_post(struct mail_save_context *ctx);
+void cydir_transaction_save_rollback(struct mail_save_context *ctx);
#endif
+++ /dev/null
-/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "cydir-storage.h"
-#include "cydir-sync.h"
-
-static void (*next_hook_mail_index_transaction_created)
- (struct mail_index_transaction *t) = NULL;
-
-static int cydir_transaction_commit(struct mail_index_transaction *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r)
-{
- struct cydir_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
- struct cydir_save_context *save_ctx;
- int ret = 0;
-
- if (dt->save_ctx != NULL) {
- if (cydir_transaction_save_commit_pre(dt->save_ctx) < 0) {
- dt->save_ctx = NULL;
- ret = -1;
- }
- }
-
- save_ctx = dt->save_ctx;
-
- if (ret < 0)
- index_transaction_finish_rollback(&dt->ictx);
- else {
- if (index_transaction_finish_commit(&dt->ictx, log_file_seq_r,
- log_file_offset_r) < 0)
- ret = -1;
- }
-
- /* transaction is destroyed now. */
- dt = NULL;
-
- if (save_ctx != NULL) {
- /* unlock uidlist file after writing to transaction log,
- to make sure we don't write uids in wrong order. */
- cydir_transaction_save_commit_post(save_ctx);
- }
- return ret;
-}
-
-static void cydir_transaction_rollback(struct mail_index_transaction *t)
-{
- struct cydir_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
-
- if (dt->save_ctx != NULL)
- cydir_transaction_save_rollback(dt->save_ctx);
-
- index_transaction_finish_rollback(&dt->ictx);
-}
-
-static void cydir_transaction_created(struct mail_index_transaction *t)
-{
- struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
-
- /* index can be for mailbox list index, in which case box=NULL */
- if (box != NULL &&
- strcmp(box->storage->name, CYDIR_STORAGE_NAME) == 0) {
- struct cydir_mailbox *cydir = (struct cydir_mailbox *)box;
- struct cydir_transaction_context *mt;
-
- mt = i_new(struct cydir_transaction_context, 1);
- mt->ictx.trans = t;
- index_transaction_init(&mt->ictx, &cydir->ibox);
-
- t->v.commit = cydir_transaction_commit;
- t->v.rollback = cydir_transaction_rollback;
- MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
- }
-
- if (next_hook_mail_index_transaction_created != NULL)
- next_hook_mail_index_transaction_created(t);
-}
-
-void cydir_transaction_class_init(void)
-{
- next_hook_mail_index_transaction_created =
- hook_mail_index_transaction_created;
- hook_mail_index_transaction_created = cydir_transaction_created;
-}
-
-void cydir_transaction_class_deinit(void)
-{
- i_assert(hook_mail_index_transaction_created ==
- cydir_transaction_created);
- hook_mail_index_transaction_created =
- next_hook_mail_index_transaction_created;
-}
dbox-sync-file.c \
dbox-sync-rebuild.c \
dbox-storage.c \
- dbox-storage-rebuild.c \
- dbox-transaction.c
+ dbox-storage-rebuild.c
headers = \
dbox-file.h \
};
struct mail_save_context *
-dbox_save_alloc(struct mailbox_transaction_context *_t)
+dbox_save_alloc(struct mailbox_transaction_context *t)
{
- struct dbox_transaction_context *t =
- (struct dbox_transaction_context *)_t;
- struct dbox_mailbox *mbox = (struct dbox_mailbox *)_t->box;
- struct dbox_save_context *ctx;
+ struct index_transaction_context *it =
+ (struct index_transaction_context *)t;
+ struct dbox_mailbox *mbox = (struct dbox_mailbox *)t->box;
+ struct dbox_save_context *ctx = (struct dbox_save_context *)t->save_ctx;
- i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
+ i_assert((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
- if (t->save_ctx != NULL) {
+ if (ctx != NULL) {
/* use the existing allocated structure */
- t->save_ctx->finished = FALSE;
- return &t->save_ctx->ctx;
+ ctx->finished = FALSE;
+ return &ctx->ctx;
}
- ctx = t->save_ctx = i_new(struct dbox_save_context, 1);
- ctx->ctx.transaction = &t->ictx.mailbox_ctx;
+ ctx = i_new(struct dbox_save_context, 1);
+ ctx->ctx.transaction = t;
ctx->mbox = mbox;
- ctx->trans = t->ictx.trans;
+ ctx->trans = it->trans;
ctx->append_ctx = dbox_map_append_begin(mbox);
i_array_init(&ctx->mails, 32);
- return &ctx->ctx;
+ t->save_ctx = &ctx->ctx;
+ return t->save_ctx;
}
static void dbox_save_add_to_index(struct dbox_save_context *ctx)
(void)dbox_save_finish(_ctx);
}
-int dbox_transaction_save_commit_pre(struct dbox_save_context *ctx)
+int dbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
{
- struct mailbox_transaction_context *_t = ctx->ctx.transaction;
+ struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
+ struct mailbox_transaction_context *_t = _ctx->transaction;
const struct mail_index_header *hdr;
uint32_t first_map_uid, last_map_uid;
if (dbox_sync_begin(ctx->mbox, DBOX_SYNC_FLAG_NO_PURGE |
DBOX_SYNC_FLAG_FORCE |
DBOX_SYNC_FLAG_FSYNC, &ctx->sync_ctx) < 0) {
- dbox_transaction_save_rollback(ctx);
+ dbox_transaction_save_rollback(_ctx);
return -1;
}
is left locked. */
if (dbox_map_append_assign_map_uids(ctx->append_ctx, &first_map_uid,
&last_map_uid) < 0) {
- dbox_transaction_save_rollback(ctx);
+ dbox_transaction_save_rollback(_ctx);
return -1;
}
if (ctx->single_count > 0) {
if (dbox_map_append_assign_uids(ctx->append_ctx,
&_t->changes->saved_uids) < 0) {
- dbox_transaction_save_rollback(ctx);
+ dbox_transaction_save_rollback(_ctx);
return -1;
}
}
FALSE);
if (dbox_map_update_refcounts(ctx->map_trans,
&ctx->copy_map_uids, 1) < 0) {
- dbox_transaction_save_rollback(ctx);
+ dbox_transaction_save_rollback(_ctx);
return -1;
}
}
return 0;
}
-void dbox_transaction_save_commit_post(struct dbox_save_context *ctx)
+void dbox_transaction_save_commit_post(struct mail_save_context *_ctx)
{
- ctx->ctx.transaction = NULL; /* transaction is already freed */
+ struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
+
+ _ctx->transaction = NULL; /* transaction is already freed */
/* finish writing the mailbox APPENDs */
if (dbox_sync_finish(&ctx->sync_ctx, TRUE) == 0) {
ctx->mbox->ibox.box.path);
}
}
- dbox_transaction_save_rollback(ctx);
+ dbox_transaction_save_rollback(_ctx);
}
-void dbox_transaction_save_rollback(struct dbox_save_context *ctx)
+void dbox_transaction_save_rollback(struct mail_save_context *_ctx)
{
+ struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx;
+
if (!ctx->finished)
dbox_save_cancel(&ctx->ctx);
if (ctx->append_ctx != NULL)
mbox->ibox.box.list = list;
mbox->ibox.mail_vfuncs = &dbox_mail_vfuncs;
+ mbox->ibox.save_commit_pre = dbox_transaction_save_commit_pre;
+ mbox->ibox.save_commit_post = dbox_transaction_save_commit_post;
+ mbox->ibox.save_rollback = dbox_transaction_save_rollback;
+
index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
DBOX_INDEX_PREFIX);
mail_index_set_fsync_types(mbox->ibox.index,
return ret;
}
-static void dbox_class_init(void)
-{
- dbox_transaction_class_init();
-}
-
-static void dbox_class_deinit(void)
-{
- dbox_transaction_class_deinit();
-}
-
static void dbox_storage_add_list(struct mail_storage *storage,
struct mailbox_list *list)
{
{
dbox_get_setting_parser_info,
- dbox_class_init,
- dbox_class_deinit,
dbox_storage_alloc,
dbox_storage_create,
dbox_storage_destroy,
unsigned int creating:1;
};
-struct dbox_transaction_context {
- struct index_transaction_context ictx;
- union mail_index_transaction_module_context module_ctx;
-
- uint32_t first_saved_mail_seq;
- struct dbox_save_context *save_ctx;
-};
-
extern struct mail_vfuncs dbox_mail_vfuncs;
-void dbox_transaction_class_init(void);
-void dbox_transaction_class_deinit(void);
-
struct mailbox *
dbox_mailbox_alloc(struct mail_storage *storage, struct mailbox_list *list,
const char *name, struct istream *input,
int dbox_save_finish(struct mail_save_context *ctx);
void dbox_save_cancel(struct mail_save_context *ctx);
-int dbox_transaction_save_commit_pre(struct dbox_save_context *ctx);
-void dbox_transaction_save_commit_post(struct dbox_save_context *ctx);
-void dbox_transaction_save_rollback(struct dbox_save_context *ctx);
+int dbox_transaction_save_commit_pre(struct mail_save_context *ctx);
+void dbox_transaction_save_commit_post(struct mail_save_context *ctx);
+void dbox_transaction_save_rollback(struct mail_save_context *ctx);
int dbox_copy(struct mail_save_context *ctx, struct mail *mail);
+++ /dev/null
-/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "dbox-storage.h"
-#include "dbox-sync.h"
-
-static void (*next_hook_mail_index_transaction_created)
- (struct mail_index_transaction *t) = NULL;
-
-static int dbox_transaction_commit(struct mail_index_transaction *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r)
-{
- struct dbox_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
- struct dbox_save_context *save_ctx;
- int ret = 0;
-
- if (dt->save_ctx != NULL) {
- if (dbox_transaction_save_commit_pre(dt->save_ctx) < 0) {
- dt->save_ctx = NULL;
- ret = -1;
- }
- }
-
- save_ctx = dt->save_ctx;
-
- if (ret < 0)
- index_transaction_finish_rollback(&dt->ictx);
- else {
- if (index_transaction_finish_commit(&dt->ictx, log_file_seq_r,
- log_file_offset_r) < 0)
- ret = -1;
- }
-
- /* transaction is destroyed now. */
- dt = NULL;
-
- if (save_ctx != NULL) {
- /* unlock uidlist file after writing to transaction log,
- to make sure we don't write uids in wrong order. */
- dbox_transaction_save_commit_post(save_ctx);
- }
- return ret;
-}
-
-static void dbox_transaction_rollback(struct mail_index_transaction *t)
-{
- struct dbox_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
-
- if (dt->save_ctx != NULL)
- dbox_transaction_save_rollback(dt->save_ctx);
-
- index_transaction_finish_rollback(&dt->ictx);
-}
-
-static void dbox_transaction_created(struct mail_index_transaction *t)
-{
- struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
-
- /* index can be for mailbox list index, in which case box=NULL */
- if (box != NULL &&
- strcmp(box->storage->name, DBOX_STORAGE_NAME) == 0) {
- struct dbox_mailbox *dbox = (struct dbox_mailbox *)box;
- struct dbox_transaction_context *mt;
-
- mt = i_new(struct dbox_transaction_context, 1);
- mt->ictx.trans = t;
- index_transaction_init(&mt->ictx, &dbox->ibox);
-
- t->v.commit = dbox_transaction_commit;
- t->v.rollback = dbox_transaction_rollback;
- MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
- }
-
- if (next_hook_mail_index_transaction_created != NULL)
- next_hook_mail_index_transaction_created(t);
-}
-
-void dbox_transaction_class_init(void)
-{
- next_hook_mail_index_transaction_created =
- hook_mail_index_transaction_created;
- hook_mail_index_transaction_created = dbox_transaction_created;
-}
-
-void dbox_transaction_class_deinit(void)
-{
- i_assert(hook_mail_index_transaction_created ==
- dbox_transaction_created);
- hook_mail_index_transaction_created =
- next_hook_mail_index_transaction_created;
-}
MAILBOX_LOCK_NOTIFY_MAILBOX_OVERRIDE
};
+struct index_transaction_context {
+ struct mailbox_transaction_context mailbox_ctx;
+ union mail_index_transaction_module_context module_ctx;
+
+ struct mail_index_transaction_vfuncs super;
+ int mail_ref_count;
+
+ struct mail_index_transaction *trans;
+ struct mail_index_view *trans_view;
+ struct mail_cache_view *cache_view;
+ struct mail_cache_transaction_ctx *cache_trans;
+};
+
struct index_mailbox {
struct mailbox box;
union mail_index_view_module_context view_module_ctx;
enum mail_index_open_flags index_flags;
+ int (*save_commit_pre)(struct mail_save_context *save_ctx);
+ void (*save_commit_post)(struct mail_save_context *save_ctx);
+ void (*save_rollback)(struct mail_save_context *save_ctx);
+
struct mail_index *index;
struct mail_index_view *view;
struct mail_cache *cache;
unsigned int move_to_memory:1;
};
-struct index_transaction_context {
- struct mailbox_transaction_context mailbox_ctx;
- struct mail_index_transaction_vfuncs super;
- int mail_ref_count;
-
- struct mail_index_transaction *trans;
- struct mail_index_view *trans_view;
- struct mail_cache_view *cache_view;
- struct mail_cache_transaction_ctx *cache_trans;
-};
-
void mail_storage_set_index_error(struct index_mailbox *ibox);
void index_storage_lock_notify(struct index_mailbox *ibox,
struct mail *mail, bool *tryagain_r);
bool index_storage_search_next_update_seq(struct mail_search_context *ctx);
-void index_transaction_init(struct index_transaction_context *t,
- struct index_mailbox *ibox);
-int index_transaction_finish_commit(struct index_transaction_context *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r);
-void index_transaction_finish_rollback(struct index_transaction_context *t);
void index_transaction_set_max_modseq(struct mailbox_transaction_context *_t,
uint64_t max_modseq,
ARRAY_TYPE(seq_range) *seqs);
struct mailbox_transaction_context *
index_transaction_begin(struct mailbox *box,
enum mailbox_transaction_flags flags);
+void index_transaction_init(struct index_transaction_context *it,
+ struct mailbox *box,
+ enum mailbox_transaction_flags flags);
int index_transaction_commit(struct mailbox_transaction_context *t,
struct mail_transaction_commit_changes *changes_r);
void index_transaction_rollback(struct mailbox_transaction_context *t);
#include "index-storage.h"
#include "index-mail.h"
-void index_transaction_init(struct index_transaction_context *t,
- struct index_mailbox *ibox)
-{
- t->mailbox_ctx.box = &ibox->box;
-
- array_create(&t->mailbox_ctx.module_contexts, default_pool,
- sizeof(void *), 5);
-
- t->trans_view = mail_index_transaction_open_updated_view(t->trans);
- t->cache_view = mail_cache_view_open(ibox->cache, t->trans_view);
- t->cache_trans = mail_cache_get_transaction(t->cache_view, t->trans);
-
- /* mail_cache_get_transaction() changes trans->v */
- t->super = t->trans->v;
-}
-
static void index_transaction_free(struct index_transaction_context *t)
{
mail_cache_view_close(t->cache_view);
i_free(t);
}
-int index_transaction_finish_commit(struct index_transaction_context *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r)
+static int
+index_transaction_index_commit(struct mail_index_transaction *index_trans,
+ uint32_t *log_file_seq_r,
+ uoff_t *log_file_offset_r)
{
- struct index_mailbox *ibox = (struct index_mailbox *)t->mailbox_ctx.box;
- int ret;
-
- i_assert(t->mail_ref_count == 0);
+ struct index_transaction_context *it =
+ MAIL_STORAGE_CONTEXT(index_trans);
+ struct mailbox_transaction_context *t = &it->mailbox_ctx;
+ struct index_mailbox *ibox = (struct index_mailbox *)t->box;
+ int ret = 0;
+
+ if (t->save_ctx != NULL) {
+ if (ibox->save_commit_pre(t->save_ctx) < 0) {
+ t->save_ctx = NULL;
+ ret = -1;
+ }
+ }
- ret = t->super.commit(t->trans, log_file_seq_r, log_file_offset_r);
+ i_assert(it->mail_ref_count == 0);
if (ret < 0)
- mail_storage_set_index_error(ibox);
+ it->super.rollback(it->trans);
+ else {
+ if (it->super.commit(it->trans, log_file_seq_r,
+ log_file_offset_r) < 0) {
+ mail_storage_set_index_error(ibox);
+ ret = -1;
+ }
+ }
- index_transaction_free(t);
+ if (t->save_ctx != NULL)
+ ibox->save_commit_post(t->save_ctx);
+
+ index_transaction_free(it);
return ret;
}
-void index_transaction_finish_rollback(struct index_transaction_context *t)
+static void index_transaction_index_rollback(struct mail_index_transaction *t)
{
- i_assert(t->mail_ref_count == 0);
+ struct index_transaction_context *it = MAIL_STORAGE_CONTEXT(t);
+ struct index_mailbox *ibox =
+ (struct index_mailbox *)it->mailbox_ctx.box;
+
+ if (it->mailbox_ctx.save_ctx != NULL)
+ ibox->save_rollback(it->mailbox_ctx.save_ctx);
- t->super.rollback(t->trans);
- index_transaction_free(t);
+ it->super.rollback(it->trans);
+ index_transaction_free(it);
}
-struct mailbox_transaction_context *
-index_transaction_begin(struct mailbox *box,
- enum mailbox_transaction_flags flags)
+void index_transaction_init(struct index_transaction_context *it,
+ struct mailbox *box,
+ enum mailbox_transaction_flags flags)
{
struct index_mailbox *ibox = (struct index_mailbox *)box;
- struct mail_index_transaction *t;
- struct index_transaction_context *it;
enum mail_index_transaction_flags trans_flags;
i_assert(box->opened);
trans_flags |= MAIL_INDEX_TRANSACTION_FLAG_EXTERNAL;
if ((flags & MAILBOX_TRANSACTION_FLAG_REFRESH) != 0)
(void)mail_index_refresh(ibox->index);
- t = mail_index_transaction_begin(ibox->view, trans_flags);
- it = MAIL_STORAGE_CONTEXT(t);
- if (it == NULL) {
- i_panic("mail storage transaction context mising for type %s",
- box->storage->name);
- }
+ it->trans = mail_index_transaction_begin(ibox->view, trans_flags);
+ it->mailbox_ctx.box = &ibox->box;
+
+ array_create(&it->mailbox_ctx.module_contexts, default_pool,
+ sizeof(void *), 5);
+
+ it->trans_view = mail_index_transaction_open_updated_view(it->trans);
+ it->cache_view = mail_cache_view_open(ibox->cache, it->trans_view);
+ it->cache_trans = mail_cache_get_transaction(it->cache_view, it->trans);
+
+ /* set up after mail_cache_get_transaction(), so that we'll still
+ have the cache_trans available in _index_commit() */
+ it->super = it->trans->v;
+ it->trans->v.commit = index_transaction_index_commit;
+ it->trans->v.rollback = index_transaction_index_rollback;
+ MODULE_CONTEXT_SET(it->trans, mail_storage_mail_index_module, it);
+}
+
+struct mailbox_transaction_context *
+index_transaction_begin(struct mailbox *box,
+ enum mailbox_transaction_flags flags)
+{
+ struct index_transaction_context *it;
+
+ it = i_new(struct index_transaction_context, 1);
+ index_transaction_init(it, box, flags);
return &it->mailbox_ctx;
}
maildir-storage.c \
maildir-sync.c \
maildir-sync-index.c \
- maildir-transaction.c \
maildir-uidlist.c \
maildir-util.c
int maildir_copy(struct mail_save_context *ctx, struct mail *mail)
{
struct mailbox_transaction_context *_t = ctx->transaction;
- struct maildir_transaction_context *t =
- (struct maildir_transaction_context *)_t;
- struct maildir_mailbox *mbox =
- (struct maildir_mailbox *)t->ictx.mailbox_ctx.box;
+ struct maildir_mailbox *mbox = (struct maildir_mailbox *)_t->box;
int ret;
i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
}
}
-struct maildir_save_context *
-maildir_save_transaction_init(struct maildir_transaction_context *t)
+static struct mail_save_context *
+maildir_save_transaction_init(struct mailbox_transaction_context *t)
{
- struct maildir_mailbox *mbox =
- (struct maildir_mailbox *)t->ictx.mailbox_ctx.box;
+ struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->box;
struct maildir_save_context *ctx;
pool_t pool;
pool = pool_alloconly_create("maildir_save_context", 4096);
ctx = p_new(pool, struct maildir_save_context, 1);
- ctx->ctx.transaction = &t->ictx.mailbox_ctx;
+ ctx->ctx.transaction = t;
ctx->pool = pool;
ctx->mbox = mbox;
- ctx->trans = t->ictx.trans;
+ ctx->trans = ((struct index_transaction_context *)t)->trans;
ctx->files_tail = &ctx->files;
ctx->fd = -1;
array_create_from_buffer(&ctx->keywords_array, &ctx->keywords_buffer,
sizeof(unsigned int));
ctx->last_save_finished = TRUE;
- return ctx;
+ return &ctx->ctx;
}
struct maildir_filename *
return t_strdup_printf("%s/%s", ctx->curdir, fname);
}
-const char *maildir_save_file_get_path(struct mailbox_transaction_context *_t,
+const char *maildir_save_file_get_path(struct mailbox_transaction_context *t,
uint32_t seq)
{
- struct maildir_transaction_context *t =
- (struct maildir_transaction_context *)_t;
- struct maildir_save_context *ctx = t->save_ctx;
+ struct maildir_save_context *save_ctx =
+ (struct maildir_save_context *)t->save_ctx;
struct maildir_filename *mf;
- i_assert(seq >= ctx->first_seq);
+ i_assert(seq >= save_ctx->first_seq);
- seq -= ctx->first_seq;
- mf = ctx->files;
+ seq -= save_ctx->first_seq;
+ mf = save_ctx->files;
while (seq > 0) {
mf = mf->next;
i_assert(mf != NULL);
seq--;
}
- return maildir_mf_get_path(ctx, mf);
+ return maildir_mf_get_path(save_ctx, mf);
}
static int maildir_create_tmp(struct maildir_mailbox *mbox, const char *dir,
}
struct mail_save_context *
-maildir_save_alloc(struct mailbox_transaction_context *_t)
+maildir_save_alloc(struct mailbox_transaction_context *t)
{
- struct maildir_transaction_context *t =
- (struct maildir_transaction_context *)_t;
-
- i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
+ i_assert((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
if (t->save_ctx == NULL)
t->save_ctx = maildir_save_transaction_init(t);
- return &t->save_ctx->ctx;
+ return t->save_ctx;
}
int maildir_save_begin(struct mail_save_context *_ctx, struct istream *input)
static void
maildir_save_rollback_index_changes(struct maildir_save_context *ctx)
{
- struct maildir_transaction_context *t =
- (struct maildir_transaction_context *)ctx->ctx.transaction;
+ struct index_transaction_context *t =
+ (struct index_transaction_context *)ctx->ctx.transaction;
uint32_t seq;
for (seq = ctx->seq; seq >= ctx->first_seq; seq--)
mail_index_expunge(ctx->trans, seq);
- mail_cache_transaction_reset(t->ictx.cache_trans);
+ mail_cache_transaction_reset(t->cache_trans);
}
static int
i_assert(!seq_range_array_iter_nth(&iter, n, &uid));
}
-int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx)
+int maildir_transaction_save_commit_pre(struct mail_save_context *_ctx)
{
- struct mailbox_transaction_context *_t = ctx->ctx.transaction;
+ struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+ struct mailbox_transaction_context *_t = _ctx->transaction;
struct maildir_filename *last_mf;
enum maildir_uidlist_sync_flags sync_flags;
int ret;
- i_assert(ctx->ctx.output == NULL);
+ i_assert(_ctx->output == NULL);
i_assert(ctx->last_save_finished);
sync_flags = MAILDIR_UIDLIST_SYNC_PARTIAL |
if (ret > 0) {
ctx->locked = TRUE;
if (maildir_save_sync_index(ctx) < 0) {
- maildir_transaction_save_rollback(ctx);
+ maildir_transaction_save_rollback(_ctx);
return -1;
}
} else if (ret == 0 &&
appends to index. */
maildir_save_rollback_index_changes(ctx);
} else {
- maildir_transaction_save_rollback(ctx);
+ maildir_transaction_save_rollback(_ctx);
return -1;
}
if (ctx->keywords_sync_ctx != NULL)
maildir_keywords_sync_deinit(&ctx->keywords_sync_ctx);
/* returning failure finishes the save_context */
- maildir_transaction_save_rollback(ctx);
+ maildir_transaction_save_rollback(_ctx);
return -1;
}
return 0;
}
-void maildir_transaction_save_commit_post(struct maildir_save_context *ctx)
+void maildir_transaction_save_commit_post(struct mail_save_context *_ctx)
{
- ctx->ctx.transaction = NULL; /* transaction is already freed */
+ struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+
+ _ctx->transaction = NULL; /* transaction is already freed */
if (ctx->locked)
maildir_uidlist_unlock(ctx->mbox->uidlist);
pool_unref(&ctx->pool);
}
-static void
-maildir_transaction_save_rollback_real(struct maildir_save_context *ctx)
+void maildir_transaction_save_rollback(struct mail_save_context *_ctx)
{
- i_assert(ctx->ctx.output == NULL);
+ struct maildir_save_context *ctx = (struct maildir_save_context *)_ctx;
+
+ i_assert(_ctx->output == NULL);
if (!ctx->last_save_finished)
maildir_save_cancel(&ctx->ctx);
mail_free(&ctx->mail);
pool_unref(&ctx->pool);
}
-
-void maildir_transaction_save_rollback(struct maildir_save_context *ctx)
-{
- T_BEGIN {
- maildir_transaction_save_rollback_real(ctx);
- } T_END;
-}
mbox->ibox.box.list = list;
mbox->ibox.mail_vfuncs = &maildir_mail_vfuncs;
+ mbox->ibox.save_commit_pre = maildir_transaction_save_commit_pre;
+ mbox->ibox.save_commit_post = maildir_transaction_save_commit_post;
+ mbox->ibox.save_rollback = maildir_transaction_save_rollback;
+
index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
MAILDIR_INDEX_PREFIX);
return mailbox_uidvalidity_next(path);
}
-static void maildir_class_init(void)
-{
- maildir_transaction_class_init();
-}
-
-static void maildir_class_deinit(void)
-{
- maildir_transaction_class_deinit();
-}
-
static void maildir_storage_add_list(struct mail_storage *storage,
struct mailbox_list *list)
{
{
maildir_get_setting_parser_info,
- maildir_class_init,
- maildir_class_deinit,
maildir_storage_alloc,
maildir_storage_create,
index_storage_destroy,
unsigned int syncing_commit:1;
};
-struct maildir_transaction_context {
- struct index_transaction_context ictx;
- union mail_index_transaction_module_context module_ctx;
-
- struct maildir_save_context *save_ctx;
-};
-
extern struct mail_vfuncs maildir_mail_vfuncs;
/* Return -1 = error, 0 = file not found, 1 = ok */
bool maildir_set_deleted(struct mailbox *box);
uint32_t maildir_get_uidvalidity_next(struct mailbox_list *list);
-void maildir_transaction_class_init(void);
-void maildir_transaction_class_deinit(void);
-
struct mail_save_context *
maildir_save_alloc(struct mailbox_transaction_context *_t);
int maildir_save_begin(struct mail_save_context *ctx, struct istream *input);
int maildir_save_finish(struct mail_save_context *ctx);
void maildir_save_cancel(struct mail_save_context *ctx);
-struct maildir_save_context *
-maildir_save_transaction_init(struct maildir_transaction_context *t);
struct maildir_filename *
maildir_save_add(struct mail_save_context *_ctx, const char *base_fname);
const char *maildir_save_file_get_path(struct mailbox_transaction_context *t,
uint32_t seq);
-int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx);
-void maildir_transaction_save_commit_post(struct maildir_save_context *ctx);
-void maildir_transaction_save_rollback(struct maildir_save_context *ctx);
+int maildir_transaction_save_commit_pre(struct mail_save_context *ctx);
+void maildir_transaction_save_commit_post(struct mail_save_context *ctx);
+void maildir_transaction_save_rollback(struct mail_save_context *ctx);
int maildir_copy(struct mail_save_context *ctx, struct mail *mail);
int maildir_transaction_copy_commit(struct maildir_copy_context *ctx);
+++ /dev/null
-/* Copyright (c) 2004-2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "maildir-storage.h"
-#include "maildir-sync.h"
-
-static void (*next_hook_mail_index_transaction_created)
- (struct mail_index_transaction *t) = NULL;
-
-static int maildir_transaction_commit(struct mail_index_transaction *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r)
-{
- struct maildir_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
- struct maildir_save_context *save_ctx;
- int ret = 0;
-
- if (mt->save_ctx != NULL) {
- if (maildir_transaction_save_commit_pre(mt->save_ctx) < 0) {
- mt->save_ctx = NULL;
- ret = -1;
- }
- }
-
- save_ctx = mt->save_ctx;
-
- if (ret == 0) {
- if (index_transaction_finish_commit(&mt->ictx, log_file_seq_r,
- log_file_offset_r) < 0)
- ret = -1;
- } else {
- index_transaction_finish_rollback(&mt->ictx);
- }
-
- /* transaction is destroyed now. */
- mt = NULL;
-
- if (save_ctx != NULL)
- maildir_transaction_save_commit_post(save_ctx);
- return ret;
-}
-
-static void maildir_transaction_rollback(struct mail_index_transaction *t)
-{
- struct maildir_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
-
- if (mt->save_ctx != NULL)
- maildir_transaction_save_rollback(mt->save_ctx);
- index_transaction_finish_rollback(&mt->ictx);
-}
-
-static void maildir_transaction_created(struct mail_index_transaction *t)
-{
- struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
-
- /* index can be for mailbox list index, in which case box=NULL */
- if (box != NULL &&
- strcmp(box->storage->name, MAILDIR_STORAGE_NAME) == 0) {
- struct maildir_mailbox *mbox = (struct maildir_mailbox *)box;
- struct maildir_transaction_context *mt;
-
- mt = i_new(struct maildir_transaction_context, 1);
- mt->ictx.trans = t;
- index_transaction_init(&mt->ictx, &mbox->ibox);
-
- t->v.commit = maildir_transaction_commit;
- t->v.rollback = maildir_transaction_rollback;
- MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
- }
- if (next_hook_mail_index_transaction_created != NULL)
- next_hook_mail_index_transaction_created(t);
-}
-
-void maildir_transaction_class_init(void)
-{
- next_hook_mail_index_transaction_created =
- hook_mail_index_transaction_created;
- hook_mail_index_transaction_created = maildir_transaction_created;
-}
-
-void maildir_transaction_class_deinit(void)
-{
- i_assert(hook_mail_index_transaction_created ==
- maildir_transaction_created);
- hook_mail_index_transaction_created =
- next_hook_mail_index_transaction_created;
-}
mbox-sync-rewrite.c \
mbox-sync-update.c \
mbox-sync.c \
- mbox-storage.c \
- mbox-transaction.c
+ mbox-storage.c
headers = \
istream-raw-mbox.h \
return 0;
}
-static void mbox_save_init_sync(struct mbox_transaction_context *t)
+static void mbox_save_init_sync(struct mailbox_transaction_context *t)
{
- struct mbox_mailbox *mbox =
- (struct mbox_mailbox *)t->ictx.mailbox_ctx.box;
- struct mbox_save_context *ctx = t->save_ctx;
+ struct mbox_mailbox *mbox = (struct mbox_mailbox *)t->box;
+ struct mbox_save_context *ctx = (struct mbox_save_context *)t->save_ctx;
const struct mail_index_header *hdr;
struct mail_index_view *view;
ctx->first_saved_uid = ctx->next_uid;
ctx->uid_validity = hdr->uid_validity;
ctx->synced = TRUE;
- t->mails_saved = TRUE;
mail_index_view_close(&view);
}
/* we're not required to assign UIDs for the appended
mails immediately. do it only if it doesn't require
syncing. */
- mbox_save_init_sync(t);
+ mbox_save_init_sync(_t);
}
}
/* we'll need to assign UID for the mail immediately. */
if (mbox_sync(mbox, 0) < 0)
return -1;
- mbox_save_init_sync(t);
+ mbox_save_init_sync(_t);
}
/* the syncing above could have changed the append offset */
}
struct mail_save_context *
-mbox_save_alloc(struct mailbox_transaction_context *_t)
+mbox_save_alloc(struct mailbox_transaction_context *t)
{
- struct mbox_transaction_context *t =
- (struct mbox_transaction_context *)_t;
- struct mbox_mailbox *mbox = (struct mbox_mailbox *)_t->box;
+ struct mbox_transaction_context *mt =
+ (struct mbox_transaction_context *)t;
+ struct mbox_mailbox *mbox = (struct mbox_mailbox *)t->box;
struct mbox_save_context *ctx;
- i_assert((_t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
-
- if (t->save_ctx != NULL)
- return &t->save_ctx->ctx;
+ i_assert((t->flags & MAILBOX_TRANSACTION_FLAG_EXTERNAL) != 0);
- ctx = t->save_ctx = i_new(struct mbox_save_context, 1);
- ctx->ctx.transaction = &t->ictx.mailbox_ctx;
- ctx->mbox = mbox;
- ctx->trans = t->ictx.trans;
- ctx->append_offset = (uoff_t)-1;
- ctx->headers = str_new(default_pool, 512);
- ctx->mail_offset = (uoff_t)-1;
- return &ctx->ctx;
+ if (t->save_ctx == NULL) {
+ ctx = i_new(struct mbox_save_context, 1);
+ ctx->ctx.transaction = t;
+ ctx->mbox = mbox;
+ ctx->trans = mt->ictx.trans;
+ ctx->append_offset = (uoff_t)-1;
+ ctx->headers = str_new(default_pool, 512);
+ ctx->mail_offset = (uoff_t)-1;
+ t->save_ctx = &ctx->ctx;
+ }
+ return t->save_ctx;
}
int mbox_save_begin(struct mail_save_context *_ctx, struct istream *input)
if (ctx->mail != NULL)
mail_free(&ctx->mail);
str_free(&ctx->headers);
- i_free(ctx);
}
-int mbox_transaction_save_commit(struct mbox_save_context *ctx)
+int mbox_transaction_save_commit_pre(struct mail_save_context *_ctx)
{
- struct mailbox_transaction_context *_t = ctx->ctx.transaction;
+ struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
+ struct mailbox_transaction_context *_t = _ctx->transaction;
struct mbox_mailbox *mbox = ctx->mbox;
struct seq_range *range;
struct stat st;
}
mbox_transaction_save_deinit(ctx);
+ if (ret < 0)
+ i_free(ctx);
return ret;
}
-void mbox_transaction_save_rollback(struct mbox_save_context *ctx)
+void mbox_transaction_save_commit_post(struct mail_save_context *_ctx)
+{
+ struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
+
+ i_assert(ctx->mbox->mbox_lock_type == F_WRLCK);
+
+ if (ctx->synced) {
+ /* after saving mails with UIDs we need to update
+ the last-uid */
+ (void)mbox_sync(ctx->mbox, MBOX_SYNC_HEADER |
+ MBOX_SYNC_REWRITE);
+ }
+ i_free(ctx);
+}
+
+void mbox_transaction_save_rollback(struct mail_save_context *_ctx)
{
+ struct mbox_save_context *ctx = (struct mbox_save_context *)_ctx;
struct mbox_mailbox *mbox = ctx->mbox;
if (!ctx->finished)
}
mbox_transaction_save_deinit(ctx);
+ i_free(ctx);
}
mbox->ibox.box.list = list;
mbox->ibox.mail_vfuncs = &mbox_mail_vfuncs;
+ mbox->ibox.save_commit_pre = mbox_transaction_save_commit_pre;
+ mbox->ibox.save_commit_post = mbox_transaction_save_commit_post;
+ mbox->ibox.save_rollback = mbox_transaction_save_rollback;
+
index_storage_mailbox_alloc(&mbox->ibox, name, input, flags,
MBOX_INDEX_PREFIX);
return 0;
}
-static void mbox_class_init(void)
-{
- mbox_transaction_class_init();
-}
-
-static void mbox_class_deinit(void)
-{
- mbox_transaction_class_deinit();
-}
-
static void mbox_storage_add_list(struct mail_storage *storage,
struct mailbox_list *list)
{
MODULE_CONTEXT_SET(list, mbox_mailbox_list_module, mlist);
}
+static struct mailbox_transaction_context *
+mbox_transaction_begin(struct mailbox *box,
+ enum mailbox_transaction_flags flags)
+{
+ struct mbox_transaction_context *mt;
+
+ mt = i_new(struct mbox_transaction_context, 1);
+ index_transaction_init(&mt->ictx, box, flags);
+ return &mt->ictx.mailbox_ctx;
+}
+
+static void mbox_transaction_unlock(struct mailbox *box, unsigned int lock_id)
+{
+ struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
+
+ if (lock_id != 0)
+ (void)mbox_unlock(mbox, lock_id);
+ if (mbox->mbox_global_lock_id == 0) {
+ i_assert(mbox->ibox.box.transaction_count > 0 ||
+ mbox->mbox_lock_type == F_UNLCK);
+ } else {
+ /* mailbox opened with MAILBOX_FLAG_KEEP_LOCKED */
+ i_assert(mbox->mbox_lock_type == F_WRLCK);
+ }
+}
+
+static int
+mbox_transaction_commit(struct mailbox_transaction_context *t,
+ struct mail_transaction_commit_changes *changes_r)
+{
+ struct mbox_transaction_context *mt =
+ (struct mbox_transaction_context *)t;
+ struct mailbox *box = t->box;
+ unsigned int lock_id = mt->mbox_lock_id;
+ int ret;
+
+ ret = index_transaction_commit(t, changes_r);
+ mbox_transaction_unlock(box, lock_id);
+ return ret;
+}
+
+static void
+mbox_transaction_rollback(struct mailbox_transaction_context *t)
+{
+ struct mbox_transaction_context *mt =
+ (struct mbox_transaction_context *)t;
+ struct mailbox *box = t->box;
+ unsigned int lock_id = mt->mbox_lock_id;
+
+ index_transaction_rollback(t);
+ mbox_transaction_unlock(box, lock_id);
+}
+
struct mail_storage mbox_storage = {
MEMBER(name) MBOX_STORAGE_NAME,
MEMBER(class_flags) MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE,
{
mbox_get_setting_parser_info,
- mbox_class_init,
- mbox_class_deinit,
mbox_storage_alloc,
mbox_storage_create,
index_storage_destroy,
index_mailbox_sync_deinit,
NULL,
mbox_notify_changes,
- index_transaction_begin,
- index_transaction_commit,
- index_transaction_rollback,
+ mbox_transaction_begin,
+ mbox_transaction_commit,
+ mbox_transaction_rollback,
index_transaction_set_max_modseq,
index_keywords_create,
index_keywords_create_from_indexes,
struct mbox_transaction_context {
struct index_transaction_context ictx;
- union mail_index_transaction_module_context module_ctx;
-
- struct mbox_save_context *save_ctx;
unsigned int mbox_lock_id;
- unsigned int mails_saved:1;
};
extern struct mail_vfuncs mbox_mail_vfuncs;
int mbox_set_syscall_error(struct mbox_mailbox *mbox, const char *function);
-void mbox_transaction_class_init(void);
-void mbox_transaction_class_deinit(void);
-
struct mailbox_sync_context *
mbox_storage_sync_init(struct mailbox *box, enum mailbox_sync_flags flags);
int mbox_save_finish(struct mail_save_context *ctx);
void mbox_save_cancel(struct mail_save_context *ctx);
-int mbox_transaction_save_commit(struct mbox_save_context *ctx);
-void mbox_transaction_save_rollback(struct mbox_save_context *ctx);
+int mbox_transaction_save_commit_pre(struct mail_save_context *ctx);
+void mbox_transaction_save_commit_post(struct mail_save_context *ctx);
+void mbox_transaction_save_rollback(struct mail_save_context *ctx);
#endif
+++ /dev/null
-/* Copyright (c) 2004-2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "mbox-storage.h"
-#include "mbox-lock.h"
-#include "mbox-sync-private.h"
-
-static void (*next_hook_mail_index_transaction_created)
- (struct mail_index_transaction *t) = NULL;
-
-static int mbox_transaction_commit(struct mail_index_transaction *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r)
-{
- struct mbox_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
- struct mbox_mailbox *mbox =
- (struct mbox_mailbox *)mt->ictx.mailbox_ctx.box;
- unsigned int lock_id = mt->mbox_lock_id;
- bool mails_saved;
- int ret = 0;
-
- if (mt->save_ctx != NULL)
- ret = mbox_transaction_save_commit(mt->save_ctx);
- mails_saved = mt->mails_saved;
-
- if (ret < 0)
- index_transaction_finish_rollback(&mt->ictx);
- else {
- if (index_transaction_finish_commit(&mt->ictx, log_file_seq_r,
- log_file_offset_r) < 0)
- ret = -1;
- }
-
- /* transaction is destroyed now. */
- mt = NULL;
-
- if (lock_id != 0 && mbox->mbox_lock_type != F_WRLCK) {
- /* unlock before writing any changes */
- (void)mbox_unlock(mbox, lock_id);
- lock_id = 0;
- }
-
- if (ret == 0 && mails_saved) {
- /* after saving mails we want to update the last-uid */
- if (mbox_sync(mbox, MBOX_SYNC_HEADER | MBOX_SYNC_REWRITE) < 0)
- ret = -1;
- }
-
- if (lock_id != 0) {
- if (mbox_unlock(mbox, lock_id) < 0)
- ret = -1;
- }
- if (mbox->mbox_global_lock_id == 0) {
- i_assert(mbox->ibox.box.transaction_count > 0 ||
- mbox->mbox_lock_type == F_UNLCK);
- } else {
- i_assert(mbox->mbox_lock_type == F_WRLCK);
- }
- return ret;
-}
-
-static void mbox_transaction_rollback(struct mail_index_transaction *t)
-{
- struct mbox_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
- struct mbox_mailbox *mbox =
- (struct mbox_mailbox *)mt->ictx.mailbox_ctx.box;
-
- if (mt->save_ctx != NULL)
- mbox_transaction_save_rollback(mt->save_ctx);
-
- if (mt->mbox_lock_id != 0)
- (void)mbox_unlock(mbox, mt->mbox_lock_id);
- index_transaction_finish_rollback(&mt->ictx);
-
- i_assert(mbox->ibox.box.transaction_count > 0 ||
- mbox->mbox_lock_type == F_UNLCK);
-}
-
-static void mbox_transaction_created(struct mail_index_transaction *t)
-{
- struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
-
- /* index can be for mailbox list index, in which case box=NULL */
- if (box != NULL && strcmp(box->storage->name, MBOX_STORAGE_NAME) == 0) {
- struct mbox_mailbox *mbox = (struct mbox_mailbox *)box;
- struct mbox_transaction_context *mt;
-
- mt = i_new(struct mbox_transaction_context, 1);
- mt->ictx.trans = t;
- index_transaction_init(&mt->ictx, &mbox->ibox);
-
- t->v.commit = mbox_transaction_commit;
- t->v.rollback = mbox_transaction_rollback;
- MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
- }
-
- if (next_hook_mail_index_transaction_created != NULL)
- next_hook_mail_index_transaction_created(t);
-}
-
-void mbox_transaction_class_init(void)
-{
- next_hook_mail_index_transaction_created =
- hook_mail_index_transaction_created;
- hook_mail_index_transaction_created = mbox_transaction_created;
-}
-
-void mbox_transaction_class_deinit(void)
-{
- i_assert(hook_mail_index_transaction_created ==
- mbox_transaction_created);
- hook_mail_index_transaction_created =
- next_hook_mail_index_transaction_created;
-}
libstorage_raw_la_SOURCES = \
raw-mail.c \
raw-sync.c \
- raw-storage.c \
- raw-transaction.c
+ raw-storage.c
headers = \
raw-storage.h \
}
}
-static void raw_class_init(void)
-{
- raw_transaction_class_init();
-}
-
-static void raw_class_deinit(void)
-{
- raw_transaction_class_deinit();
-}
-
static void raw_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
struct mailbox_list *list)
{
{
NULL,
- raw_class_init,
- raw_class_deinit,
raw_storage_alloc,
NULL,
index_storage_destroy,
extern struct mail_vfuncs raw_mail_vfuncs;
-void raw_transaction_class_init(void);
-void raw_transaction_class_deinit(void);
-
#endif
+++ /dev/null
-/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
-
-#include "lib.h"
-#include "array.h"
-#include "raw-storage.h"
-
-struct raw_transaction_context {
- struct index_transaction_context ictx;
- union mail_index_transaction_module_context module_ctx;
-};
-
-static void (*next_hook_mail_index_transaction_created)
- (struct mail_index_transaction *t) = NULL;
-
-static int
-raw_transaction_commit(struct mail_index_transaction *t,
- uint32_t *log_file_seq_r, uoff_t *log_file_offset_r)
-{
- struct raw_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
-
- return index_transaction_finish_commit(&mt->ictx, log_file_seq_r,
- log_file_offset_r);
-}
-
-static void raw_transaction_rollback(struct mail_index_transaction *t)
-{
- struct raw_transaction_context *mt = MAIL_STORAGE_CONTEXT(t);
-
- index_transaction_finish_rollback(&mt->ictx);
-}
-
-static void raw_transaction_created(struct mail_index_transaction *t)
-{
- struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
-
- /* index can be for mailbox list index, in which case box=NULL */
- if (box != NULL &&
- strcmp(box->storage->name, RAW_STORAGE_NAME) == 0) {
- struct raw_mailbox *raw = (struct raw_mailbox *)box;
- struct raw_transaction_context *mt;
-
- mt = i_new(struct raw_transaction_context, 1);
- mt->ictx.trans = t;
- index_transaction_init(&mt->ictx, &raw->ibox);
-
- t->v.commit = raw_transaction_commit;
- t->v.rollback = raw_transaction_rollback;
- MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
- }
-
- if (next_hook_mail_index_transaction_created != NULL)
- next_hook_mail_index_transaction_created(t);
-}
-
-void raw_transaction_class_init(void)
-{
- next_hook_mail_index_transaction_created =
- hook_mail_index_transaction_created;
- hook_mail_index_transaction_created = raw_transaction_created;
-}
-
-void raw_transaction_class_deinit(void)
-{
- i_assert(hook_mail_index_transaction_created ==
- raw_transaction_created);
- hook_mail_index_transaction_created =
- next_hook_mail_index_transaction_created;
-}
MEMBER(class_flags) 0, /* unknown at this point */
{
- NULL,
- NULL,
NULL,
shared_storage_alloc,
shared_storage_create,
struct mail_storage_vfuncs {
const struct setting_parser_info *(*get_setting_parser_info)(void);
- void (*class_init)(void);
- void (*class_deinit)(void);
-
struct mail_storage *(*alloc)(void);
int (*create)(struct mail_storage *storage, struct mail_namespace *ns,
const char **error_r);
struct mail_transaction_commit_changes *changes;
ARRAY_DEFINE(module_contexts,
union mailbox_transaction_module_context *);
+
+ struct mail_save_context *save_ctx;
};
union mail_search_module_context {
{
i_assert(mail_storage_find_class(storage_class->name) == NULL);
- if (storage_class->v.class_init != NULL)
- storage_class->v.class_init();
-
/* append it after the list, so the autodetection order is correct */
array_append(&mail_storage_classes, &storage_class, 1);
}
break;
}
}
-
- if (storage_class->v.class_deinit != NULL)
- storage_class->v.class_deinit();
}
struct mail_storage *mail_storage_find_class(const char *name)
MEMBER(class_flags) 0,
{
- NULL,
- NULL,
NULL,
test_storage_alloc,
NULL,
struct mailbox_transaction_context *backend_trans;
struct virtual_save_context *ctx;
- if (t->save_ctx != NULL)
- return &t->save_ctx->ctx;
+ if (_t->save_ctx != NULL)
+ return _t->save_ctx;
- ctx = t->save_ctx = i_new(struct virtual_save_context, 1);
+ ctx = i_new(struct virtual_save_context, 1);
ctx->ctx.transaction = &t->ictx.mailbox_ctx;
if (mbox->save_bbox != NULL) {
virtual_transaction_get(_t, mbox->save_bbox->box);
ctx->backend_save_ctx = mailbox_save_alloc(backend_trans);
}
- return &ctx->ctx;
+ _t->save_ctx = &ctx->ctx;
+ return _t->save_ctx;
}
static struct mail_keywords *
mailbox_save_cancel(&ctx->backend_save_ctx);
}
-void virtual_save_free(struct virtual_save_context *ctx)
+void virtual_save_free(struct mail_save_context *_ctx)
{
+ struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
+
if (ctx->backend_keywords != NULL)
mailbox_keywords_unref(ctx->backend_box, &ctx->backend_keywords);
if (ctx->backend_save_ctx != NULL)
return index_storage_is_inconsistent(box);
}
-static void virtual_class_init(void)
-{
- virtual_transaction_class_init();
-}
-
-static void virtual_class_deinit(void)
-{
- virtual_transaction_class_deinit();
-}
-
static void virtual_storage_add_list(struct mail_storage *storage ATTR_UNUSED,
struct mailbox_list *list)
{
{
NULL,
- virtual_class_init,
- virtual_class_deinit,
virtual_storage_alloc,
NULL,
index_storage_destroy,
index_mailbox_sync_deinit,
NULL,
virtual_notify_changes,
- index_transaction_begin,
- index_transaction_commit,
- index_transaction_rollback,
+ virtual_transaction_begin,
+ virtual_transaction_commit,
+ virtual_transaction_rollback,
index_transaction_set_max_modseq,
index_keywords_create,
index_keywords_create_from_indexes,
int virtual_save_continue(struct mail_save_context *ctx);
int virtual_save_finish(struct mail_save_context *ctx);
void virtual_save_cancel(struct mail_save_context *ctx);
-void virtual_save_free(struct virtual_save_context *ctx);
+void virtual_save_free(struct mail_save_context *ctx);
void virtual_box_copy_error(struct mailbox *dest, struct mailbox *src);
-void virtual_transaction_class_init(void);
-void virtual_transaction_class_deinit(void);
-
#endif
#include "virtual-storage.h"
#include "virtual-transaction.h"
-static void (*next_hook_mail_index_transaction_created)
- (struct mail_index_transaction *t) = NULL;
-
struct mailbox_transaction_context *
virtual_transaction_get(struct mailbox_transaction_context *trans,
struct mailbox *backend_box)
{
- struct virtual_transaction_context *dt =
+ struct virtual_transaction_context *vt =
(struct virtual_transaction_context *)trans;
struct mailbox_transaction_context *const *bt, *new_bt;
unsigned int i, count;
- bt = array_get(&dt->backend_transactions, &count);
+ bt = array_get(&vt->backend_transactions, &count);
for (i = 0; i < count; i++) {
if (bt[i]->box == backend_box)
return bt[i];
}
new_bt = mailbox_transaction_begin(backend_box, trans->flags);
- array_append(&dt->backend_transactions, &new_bt, 1);
+ array_append(&vt->backend_transactions, &new_bt, 1);
return new_bt;
}
-static int virtual_transaction_commit(struct mail_index_transaction *t,
- uint32_t *log_file_seq_r,
- uoff_t *log_file_offset_r)
+struct mailbox_transaction_context *
+virtual_transaction_begin(struct mailbox *box,
+ enum mailbox_transaction_flags flags)
+{
+ struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
+ struct virtual_transaction_context *vt;
+
+ vt = i_new(struct virtual_transaction_context, 1);
+ i_array_init(&vt->backend_transactions,
+ array_count(&mbox->backend_boxes));
+ index_transaction_init(&vt->ictx, box, flags);
+ return &vt->ictx.mailbox_ctx;
+}
+
+int virtual_transaction_commit(struct mailbox_transaction_context *t,
+ struct mail_transaction_commit_changes *changes_r)
{
- struct virtual_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
+ struct virtual_transaction_context *vt =
+ (struct virtual_transaction_context *)t;
struct mailbox_transaction_context **bt;
unsigned int i, count;
int ret = 0;
- if (dt->save_ctx != NULL)
- virtual_save_free(dt->save_ctx);
+ if (t->save_ctx != NULL) {
+ virtual_save_free(t->save_ctx);
+ t->save_ctx = NULL;
+ }
- bt = array_get_modifiable(&dt->backend_transactions, &count);
+ bt = array_get_modifiable(&vt->backend_transactions, &count);
for (i = 0; i < count; i++) {
if (mailbox_transaction_commit(&bt[i]) < 0)
ret = -1;
}
- array_free(&dt->backend_transactions);
+ array_free(&vt->backend_transactions);
- if (index_transaction_finish_commit(&dt->ictx, log_file_seq_r,
- log_file_offset_r) < 0)
+ if (index_transaction_commit(t, changes_r) < 0)
ret = -1;
return ret;
}
-static void virtual_transaction_rollback(struct mail_index_transaction *t)
+void virtual_transaction_rollback(struct mailbox_transaction_context *t)
{
- struct virtual_transaction_context *dt = MAIL_STORAGE_CONTEXT(t);
+ struct virtual_transaction_context *vt =
+ (struct virtual_transaction_context *)t;
struct mailbox_transaction_context **bt;
unsigned int i, count;
- if (dt->save_ctx != NULL)
- virtual_save_free(dt->save_ctx);
+ if (t->save_ctx != NULL) {
+ virtual_save_free(t->save_ctx);
+ t->save_ctx = NULL;
+ }
- bt = array_get_modifiable(&dt->backend_transactions, &count);
+ bt = array_get_modifiable(&vt->backend_transactions, &count);
for (i = 0; i < count; i++)
mailbox_transaction_rollback(&bt[i]);
- array_free(&dt->backend_transactions);
-
- index_transaction_finish_rollback(&dt->ictx);
-}
-
-static void virtual_transaction_created(struct mail_index_transaction *t)
-{
- struct mailbox *box = MAIL_STORAGE_CONTEXT(t->view);
+ array_free(&vt->backend_transactions);
- /* index can be for mailbox list index, in which case box=NULL */
- if (box != NULL &&
- strcmp(box->storage->name, VIRTUAL_STORAGE_NAME) == 0) {
- struct virtual_mailbox *mbox = (struct virtual_mailbox *)box;
- struct virtual_transaction_context *mt;
-
- mt = i_new(struct virtual_transaction_context, 1);
- mt->ictx.trans = t;
- mt->ictx.super = t->v;
-
- t->v.commit = virtual_transaction_commit;
- t->v.rollback = virtual_transaction_rollback;
- MODULE_CONTEXT_SET(t, mail_storage_mail_index_module, mt);
-
- i_array_init(&mt->backend_transactions,
- array_count(&mbox->backend_boxes));
- index_transaction_init(&mt->ictx, &mbox->ibox);
- }
-
- if (next_hook_mail_index_transaction_created != NULL)
- next_hook_mail_index_transaction_created(t);
-}
-
-void virtual_transaction_class_init(void)
-{
- next_hook_mail_index_transaction_created =
- hook_mail_index_transaction_created;
- hook_mail_index_transaction_created = virtual_transaction_created;
-}
-
-void virtual_transaction_class_deinit(void)
-{
- i_assert(hook_mail_index_transaction_created ==
- virtual_transaction_created);
- hook_mail_index_transaction_created =
- next_hook_mail_index_transaction_created;
+ index_transaction_rollback(t);
}
struct virtual_transaction_context {
struct index_transaction_context ictx;
- union mail_index_transaction_module_context module_ctx;
-
- struct virtual_save_context *save_ctx;
ARRAY_DEFINE(backend_transactions,
struct mailbox_transaction_context *);
virtual_transaction_get(struct mailbox_transaction_context *trans,
struct mailbox *backend_box);
-void virtual_transaction_class_init(void);
-void virtual_transaction_class_deinit(void);
+struct mailbox_transaction_context *
+virtual_transaction_begin(struct mailbox *box,
+ enum mailbox_transaction_flags flags);
+int virtual_transaction_commit(struct mailbox_transaction_context *t,
+ struct mail_transaction_commit_changes *changes_r);
+void virtual_transaction_rollback(struct mailbox_transaction_context *t);
#endif