diff --git a/src/plugins/notify/notify-storage.c b/src/plugins/notify/notify-storage.c index 0398059342..8d79aca0ab 100644 --- a/src/plugins/notify/notify-storage.c +++ b/src/plugins/notify/notify-storage.c @@ -11,11 +11,6 @@ #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, @@ -95,19 +90,10 @@ static void notify_mail_allocated(struct mail *_mail) 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; @@ -122,23 +108,6 @@ notify_copy(struct mail_save_context *ctx, struct mail *mail) 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) { @@ -160,13 +129,9 @@ notify_transaction_begin(struct mailbox *box, { 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; @@ -176,14 +141,9 @@ static int 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; @@ -199,13 +159,8 @@ notify_transaction_commit(struct mailbox_transaction_context *t, 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); @@ -284,7 +239,6 @@ static void notify_mailbox_allocated(struct mailbox *box) 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; diff --git a/src/plugins/quota/quota-storage.c b/src/plugins/quota/quota-storage.c index fb99c298ea..88815851ba 100644 --- a/src/plugins/quota/quota-storage.c +++ b/src/plugins/quota/quota-storage.c @@ -142,8 +142,7 @@ quota_mailbox_transaction_commit(struct mailbox_transaction_context *ctx, 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); @@ -160,8 +159,7 @@ quota_mailbox_transaction_rollback(struct mailbox_transaction_context *ctx) 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); @@ -254,14 +252,9 @@ quota_copy(struct mail_save_context *ctx, struct mail *mail) 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); @@ -311,14 +304,9 @@ quota_save_begin(struct mail_save_context *ctx, struct istream *input) } } - 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); diff --git a/src/plugins/virtual/virtual-save.c b/src/plugins/virtual/virtual-save.c index 492b97f485..c8671bca71 100644 --- a/src/plugins/virtual/virtual-save.c +++ b/src/plugins/virtual/virtual-save.c @@ -113,11 +113,8 @@ int virtual_save_begin(struct mail_save_context *_ctx, struct istream *input) 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); } diff --git a/src/plugins/zlib/zlib-plugin.c b/src/plugins/zlib/zlib-plugin.c index cd9beedaac..2435678651 100644 --- a/src/plugins/zlib/zlib-plugin.c +++ b/src/plugins/zlib/zlib-plugin.c @@ -31,12 +31,6 @@ struct zlib_mail { 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; @@ -62,6 +56,14 @@ static MODULE_CONTEXT_DEFINE_INIT(zlib_storage_module, &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; @@ -179,12 +181,11 @@ static void zlib_mail_close(struct mail *_mail) 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); @@ -196,69 +197,6 @@ static void zlib_mail_allocated(struct mail *_mail) 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; @@ -310,11 +248,7 @@ zlib_permail_alloc_init(struct mailbox *box, struct mailbox_vfuncs *v) { 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; @@ -384,7 +318,6 @@ static void zlib_mailbox_allocated(struct mailbox *box) { 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; @@ -394,8 +327,7 @@ static void zlib_mailbox_allocated(struct mailbox *box) 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); }