#define NOTIFY_MAIL_CONTEXT(obj) \
MODULE_CONTEXT(obj, notify_mail_module)
-struct notify_transaction_context {
- union mailbox_transaction_module_context module_ctx;
- struct mail *tmp_mail;
-};
-
static MODULE_CONTEXT_DEFINE_INIT(notify_storage_module,
&mail_storage_module_register);
static MODULE_CONTEXT_DEFINE_INIT(notify_mail_module,
static int
notify_copy(struct mail_save_context *ctx, struct mail *mail)
{
- struct notify_transaction_context *lt =
- NOTIFY_CONTEXT(ctx->transaction);
union mailbox_module_context *lbox =
NOTIFY_CONTEXT(ctx->transaction->box);
int ret;
- if (ctx->dest_mail == NULL &&
- (ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) {
- if (lt->tmp_mail == NULL)
- lt->tmp_mail = mail_alloc(ctx->transaction, 0, NULL);
- ctx->dest_mail = lt->tmp_mail;
- }
-
if ((ret = lbox->super.copy(ctx, mail)) < 0)
return -1;
return ret;
}
-static int
-notify_save_begin(struct mail_save_context *ctx, struct istream *input)
-{
- struct notify_transaction_context *lt =
- NOTIFY_CONTEXT(ctx->transaction);
- union mailbox_module_context *lbox =
- NOTIFY_CONTEXT(ctx->transaction->box);
-
- if (ctx->dest_mail == NULL &&
- (ctx->transaction->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0) {
- if (lt->tmp_mail == NULL)
- lt->tmp_mail = mail_alloc(ctx->transaction, 0, NULL);
- ctx->dest_mail = lt->tmp_mail;
- }
- return lbox->super.save_begin(ctx, input);
-}
-
static int
notify_save_finish(struct mail_save_context *ctx)
{
{
union mailbox_module_context *lbox = NOTIFY_CONTEXT(box);
struct mailbox_transaction_context *t;
- struct notify_transaction_context *lt;
t = lbox->super.transaction_begin(box, flags);
- lt = i_new(struct notify_transaction_context, 1);
- MODULE_CONTEXT_SET(t, notify_storage_module, lt);
-
if ((t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0)
notify_contexts_mail_transaction_begin(t);
return t;
notify_transaction_commit(struct mailbox_transaction_context *t,
struct mail_transaction_commit_changes *changes_r)
{
- struct notify_transaction_context *lt = NOTIFY_CONTEXT(t);
union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box);
bool no_notify = (t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) != 0;
- if (lt->tmp_mail != NULL)
- mail_free(<->tmp_mail);
- i_free(lt);
-
if ((lbox->super.transaction_commit(t, changes_r)) < 0) {
notify_contexts_mail_transaction_rollback(t);
return -1;
static void
notify_transaction_rollback(struct mailbox_transaction_context *t)
{
- struct notify_transaction_context *lt = NOTIFY_CONTEXT(t);
union mailbox_module_context *lbox = NOTIFY_CONTEXT(t->box);
- if (lt->tmp_mail != NULL)
- mail_free(<->tmp_mail);
- i_free(lt);
-
if ((t->flags & MAILBOX_TRANSACTION_FLAG_NO_NOTIFY) == 0)
notify_contexts_mail_transaction_rollback(t);
lbox->super.transaction_rollback(t);
box->vlast = &lbox->super;
v->copy = notify_copy;
- v->save_begin = notify_save_begin;
v->save_finish = notify_save_finish;
v->transaction_begin = notify_transaction_begin;
v->transaction_commit = notify_transaction_commit;
struct quota_mailbox *qbox = QUOTA_CONTEXT(ctx->box);
struct quota_transaction_context *qt = QUOTA_CONTEXT(ctx);
- if (qt->tmp_mail != NULL)
- mail_free(&qt->tmp_mail);
+ i_assert(qt->tmp_mail == NULL);
if (qbox->module_ctx.super.transaction_commit(ctx, changes_r) < 0) {
quota_transaction_rollback(&qt);
struct quota_mailbox *qbox = QUOTA_CONTEXT(ctx->box);
struct quota_transaction_context *qt = QUOTA_CONTEXT(ctx);
- if (qt->tmp_mail != NULL)
- mail_free(&qt->tmp_mail);
+ i_assert(qt->tmp_mail == NULL);
qbox->module_ctx.super.transaction_rollback(ctx);
quota_transaction_rollback(&qt);
struct quota_transaction_context *qt = QUOTA_CONTEXT(t);
struct quota_mailbox *qbox = QUOTA_CONTEXT(t->box);
- if (ctx->dest_mail == NULL) {
- /* we always want to know the mail size */
- if (qt->tmp_mail == NULL) {
- qt->tmp_mail = mail_alloc(t, MAIL_FETCH_PHYSICAL_SIZE,
- NULL);
- }
- ctx->dest_mail = qt->tmp_mail;
- }
+ /* we always want to know the mail size */
+ mail_add_temp_wanted_fields(ctx->dest_mail, MAIL_FETCH_PHYSICAL_SIZE, NULL);
+
/* get quota before copying any mails. this avoids .vsize.lock
deadlocks with backends that lock mails for expunging/copying. */
(void)quota_transaction_set_limits(qt);
}
}
- if (ctx->dest_mail == NULL) {
- /* we always want to know the mail size */
- if (qt->tmp_mail == NULL) {
- qt->tmp_mail = mail_alloc(t, MAIL_FETCH_PHYSICAL_SIZE,
- NULL);
- }
- ctx->dest_mail = qt->tmp_mail;
- }
+ /* we always want to know the mail size */
+ mail_add_temp_wanted_fields(ctx->dest_mail, MAIL_FETCH_PHYSICAL_SIZE, NULL);
+
/* get quota before copying any mails. this avoids .vsize.lock
deadlocks with backends that lock mails for expunging/copying. */
(void)quota_transaction_set_limits(qt);
mailbox_save_set_guid(ctx->backend_save_ctx, mdata->guid);
mailbox_save_set_min_modseq(ctx->backend_save_ctx, mdata->min_modseq);
- if (_ctx->dest_mail != NULL) {
- mail = virtual_mail_set_backend_mail(_ctx->dest_mail,
- mbox->save_bbox);
- mailbox_save_set_dest_mail(ctx->backend_save_ctx, mail);
- }
+ mail = virtual_mail_set_backend_mail(_ctx->dest_mail, mbox->save_bbox);
+ mailbox_save_set_dest_mail(ctx->backend_save_ctx, mail);
return mailbox_save_begin(&ctx->backend_save_ctx, input);
}
bool verifying_save;
};
-struct zlib_transaction_context {
- union mailbox_transaction_module_context module_ctx;
-
- struct mail *tmp_mail;
-};
-
struct zlib_mail_cache {
struct timeout *to;
struct mailbox *box;
&mail_storage_module_register);
static MODULE_CONTEXT_DEFINE_INIT(zlib_mail_module, &mail_module_register);
+static bool zlib_mailbox_is_permail(struct mailbox *box)
+{
+ enum mail_storage_class_flags class_flags = box->storage->class_flags;
+
+ return (class_flags & MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS) == 0 &&
+ (class_flags & MAIL_STORAGE_CLASS_FLAG_BINARY_DATA) != 0;
+}
+
static void zlib_mail_cache_close(struct zlib_user *zuser)
{
struct zlib_mail_cache *cache = &zuser->cache;
static void zlib_mail_allocated(struct mail *_mail)
{
- struct zlib_transaction_context *zt = ZLIB_CONTEXT(_mail->transaction);
struct mail_private *mail = (struct mail_private *)_mail;
struct mail_vfuncs *v = mail->vlast;
struct zlib_mail *zmail;
- if (zt == NULL)
+ if (!zlib_mailbox_is_permail(_mail->box))
return;
zmail = p_new(mail->pool, struct zlib_mail, 1);
MODULE_CONTEXT_SET(mail, zlib_mail_module, zmail);
}
-static struct mailbox_transaction_context *
-zlib_mailbox_transaction_begin(struct mailbox *box,
- enum mailbox_transaction_flags flags)
-{
- union mailbox_module_context *zbox = ZLIB_CONTEXT(box);
- struct mailbox_transaction_context *t;
- struct zlib_transaction_context *zt;
-
- t = zbox->super.transaction_begin(box, flags);
-
- zt = i_new(struct zlib_transaction_context, 1);
-
- MODULE_CONTEXT_SET(t, zlib_storage_module, zt);
- return t;
-}
-
-static void
-zlib_mailbox_transaction_rollback(struct mailbox_transaction_context *t)
-{
- union mailbox_module_context *zbox = ZLIB_CONTEXT(t->box);
- struct zlib_transaction_context *zt = ZLIB_CONTEXT(t);
-
- if (zt->tmp_mail != NULL)
- mail_free(&zt->tmp_mail);
-
- zbox->super.transaction_rollback(t);
- i_free(zt);
-}
-
-static int
-zlib_mailbox_transaction_commit(struct mailbox_transaction_context *t,
- struct mail_transaction_commit_changes *changes_r)
-{
- union mailbox_module_context *zbox = ZLIB_CONTEXT(t->box);
- struct zlib_transaction_context *zt = ZLIB_CONTEXT(t);
- int ret;
-
- if (zt->tmp_mail != NULL)
- mail_free(&zt->tmp_mail);
-
- ret = zbox->super.transaction_commit(t, changes_r);
- i_free(zt);
- return ret;
-}
-
-static int
-zlib_mail_save_begin(struct mail_save_context *ctx, struct istream *input)
-{
- struct mailbox_transaction_context *t = ctx->transaction;
- struct zlib_transaction_context *zt = ZLIB_CONTEXT(t);
- union mailbox_module_context *zbox = ZLIB_CONTEXT(t->box);
-
- if (ctx->dest_mail == NULL) {
- if (zt->tmp_mail == NULL) {
- zt->tmp_mail = mail_alloc(t, MAIL_FETCH_PHYSICAL_SIZE,
- NULL);
- }
- ctx->dest_mail = zt->tmp_mail;
- }
-
- return zbox->super.save_begin(ctx, input);
-}
-
static int zlib_mail_save_finish(struct mail_save_context *ctx)
{
struct mailbox *box = ctx->transaction->box;
{
struct zlib_user *zuser = ZLIB_USER_CONTEXT(box->storage->user);
- v->transaction_begin = zlib_mailbox_transaction_begin;
- v->transaction_rollback = zlib_mailbox_transaction_rollback;
- v->transaction_commit = zlib_mailbox_transaction_commit;
if (zuser->save_handler == NULL) {
- v->save_begin = zlib_mail_save_begin;
v->save_finish = zlib_mail_save_finish;
} else {
v->save_begin = zlib_mail_save_compress_begin;
{
struct mailbox_vfuncs *v = box->vlast;
union mailbox_module_context *zbox;
- enum mail_storage_class_flags class_flags = box->storage->class_flags;
zbox = p_new(box->pool, union mailbox_module_context, 1);
zbox->super = *v;
MODULE_CONTEXT_SET_SELF(box, zlib_storage_module, zbox);
- if ((class_flags & MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS) == 0 &&
- (class_flags & MAIL_STORAGE_CLASS_FLAG_BINARY_DATA) != 0)
+ if (zlib_mailbox_is_permail(box))
zlib_permail_alloc_init(box, v);
}