Mercurial > dovecot > core-2.2
changeset 21539:eafb085567bb
lib-storage: Always create mail_save_context.dest_mail
This allows removing similar mail_alloc() from storage backends and plugins
that need it.
As a side effect, this changes mbox code to always assign UIDs to saved
mails. This shouldn't be much of a problem, since it happened practically
always already.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Thu, 09 Feb 2017 16:53:47 +0200 |
parents | cbb4cb127366 |
children | 6a69f65921ea |
files | src/lib-storage/index/index-transaction.c src/lib-storage/mail-storage-private.h src/lib-storage/mail-storage.c |
diffstat | 3 files changed, 47 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/index-transaction.c Thu Feb 09 16:34:52 2017 +0200 +++ b/src/lib-storage/index/index-transaction.c Thu Feb 09 16:53:47 2017 +0200 @@ -47,6 +47,7 @@ } if (t->save_ctx != NULL) { + mailbox_save_context_deinit(t->save_ctx); if (ret < 0) { t->box->v.transaction_save_rollback(t->save_ctx); t->save_ctx = NULL; @@ -76,8 +77,10 @@ } } - if (t->save_ctx != NULL) + if (t->save_ctx != NULL) { + i_assert(t->save_ctx->dest_mail == NULL); t->box->v.transaction_save_commit_post(t->save_ctx, result_r); + } if (pvt_sync_ctx != NULL) { if (index_mailbox_sync_pvt_newmails(pvt_sync_ctx, t) < 0) { @@ -97,8 +100,10 @@ struct mailbox_transaction_context *t = MAIL_STORAGE_CONTEXT(index_trans); - if (t->save_ctx != NULL) + if (t->save_ctx != NULL) { + mailbox_save_context_deinit(t->save_ctx); t->box->v.transaction_save_rollback(t->save_ctx); + } i_assert(t->mail_ref_count == 0); t->super.rollback(index_trans);
--- a/src/lib-storage/mail-storage-private.h Thu Feb 09 16:34:52 2017 +0200 +++ b/src/lib-storage/mail-storage-private.h Thu Feb 09 16:53:47 2017 +0200 @@ -674,6 +674,8 @@ /* mail is being copied or moved. However, this is set also with mailbox_save_using_mail() and then saving==TRUE. */ unsigned int copying_or_moving:1; + /* dest_mail was set via mailbox_save_set_dest_mail() */ + unsigned int dest_mail_external:1; }; struct mailbox_sync_context { @@ -766,5 +768,6 @@ enum mail_index_open_flags mail_storage_settings_to_index_flags(const struct mail_storage_settings *set); +void mailbox_save_context_deinit(struct mail_save_context *ctx); #endif
--- a/src/lib-storage/mail-storage.c Thu Feb 09 16:34:52 2017 +0200 +++ b/src/lib-storage/mail-storage.c Thu Feb 09 16:53:47 2017 +0200 @@ -2008,6 +2008,13 @@ return t->box; } +static void mailbox_save_dest_mail_close(struct mail_save_context *ctx) +{ + struct mail_private *mail = (struct mail_private *)ctx->dest_mail; + + mail->v.close(&mail->mail); +} + struct mail_save_context * mailbox_save_alloc(struct mailbox_transaction_context *t) { @@ -2020,9 +2027,28 @@ ctx->unfinished = TRUE; ctx->data.received_date = (time_t)-1; ctx->data.save_date = (time_t)-1; + + /* Always have a dest_mail available. A lot of plugins make use + of this. */ + if (ctx->dest_mail == NULL) + ctx->dest_mail = mail_alloc(t, 0, NULL); + else { + /* make sure the mail isn't used before mail_set_seq_saving() */ + mailbox_save_dest_mail_close(ctx); + } return ctx; } +void mailbox_save_context_deinit(struct mail_save_context *ctx) +{ + i_assert(ctx->dest_mail != NULL); + + if (!ctx->dest_mail_external) + mail_free(&ctx->dest_mail); + else + ctx->dest_mail = NULL; +} + void mailbox_save_set_flags(struct mail_save_context *ctx, enum mail_flags flags, struct mail_keywords *keywords) @@ -2117,7 +2143,12 @@ void mailbox_save_set_dest_mail(struct mail_save_context *ctx, struct mail *mail) { + i_assert(mail != NULL); + + if (!ctx->dest_mail_external) + mail_free(&ctx->dest_mail); ctx->dest_mail = mail; + ctx->dest_mail_external = TRUE; } int mailbox_save_begin(struct mail_save_context **ctx, struct istream *input) @@ -2244,7 +2275,6 @@ { struct mail_save_context *ctx = *_ctx; struct mail_keywords *keywords = ctx->data.keywords; - struct mail_private *mail; *_ctx = NULL; T_BEGIN { @@ -2252,13 +2282,12 @@ } T_END; if (keywords != NULL && !ctx->finishing) mailbox_keywords_unref(&keywords); - if (ctx->dest_mail != NULL) { - /* the dest_mail is no longer valid. if we're still saving - more mails, the mail sequence may get reused. make sure - the mail gets reset in between */ - mail = (struct mail_private *)ctx->dest_mail; - mail->v.close(&mail->mail); - } + + /* the dest_mail is no longer valid. if we're still saving + more mails, the mail sequence may get reused. make sure + the mail gets reset in between */ + mailbox_save_dest_mail_close(ctx); + mailbox_save_context_reset(ctx, FALSE); }