From: Timo Sirainen Date: Fri, 28 Apr 2017 11:06:43 +0000 (+0300) Subject: lib-storage: Move backend code to a common index_storage_save_abort_last() X-Git-Tag: 2.2.30.rc1~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d670c0cf2532c7ef9bd81e9cc302615c444b337c;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Move backend code to a common index_storage_save_abort_last() Conflicts: src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h --- diff --git a/src/lib-storage/index/dbox-multi/mdbox-save.c b/src/lib-storage/index/dbox-multi/mdbox-save.c index db50757cdd..86fdb7ec26 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-save.c +++ b/src/lib-storage/index/dbox-multi/mdbox-save.c @@ -216,8 +216,7 @@ static int mdbox_save_finish_write(struct mail_save_context *_ctx) i_stream_unref(&ctx->ctx.input); if (ctx->ctx.failed) { - mail_index_expunge(ctx->ctx.trans, ctx->ctx.seq); - mail_cache_transaction_reset(ctx->ctx.ctx.transaction->cache_trans); + index_storage_save_abort_last(&ctx->ctx.ctx, ctx->ctx.seq); mdbox_map_append_abort(ctx->append_ctx); array_delete(&ctx->mails, array_count(&ctx->mails) - 1, 1); return -1; diff --git a/src/lib-storage/index/dbox-single/sdbox-save.c b/src/lib-storage/index/dbox-single/sdbox-save.c index 95ff5c256c..feb2fd28c1 100644 --- a/src/lib-storage/index/dbox-single/sdbox-save.c +++ b/src/lib-storage/index/dbox-single/sdbox-save.c @@ -195,8 +195,7 @@ static int dbox_save_finish_write(struct mail_save_context *_ctx) } T_END; if (ctx->ctx.failed) { - mail_index_expunge(ctx->ctx.trans, ctx->ctx.seq); - mail_cache_transaction_reset(ctx->ctx.ctx.transaction->cache_trans); + index_storage_save_abort_last(&ctx->ctx.ctx, ctx->ctx.seq); dbox_file_append_rollback(&ctx->append_ctx); dbox_file_unlink(*files); dbox_file_unref(files); diff --git a/src/lib-storage/index/index-storage.c b/src/lib-storage/index/index-storage.c index 1f0c070858..8222dc974b 100644 --- a/src/lib-storage/index/index-storage.c +++ b/src/lib-storage/index/index-storage.c @@ -1072,3 +1072,53 @@ int index_storage_expunged_sync_begin(struct mailbox *box, } return 1; } + +int index_storage_save_continue(struct mail_save_context *ctx, + struct istream *input, + struct mail *cache_dest_mail) +{ + struct mail_storage *storage = ctx->transaction->box->storage; + + do { + switch (o_stream_send_istream(ctx->data.output, input)) { + case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: + break; + case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: + break; + case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: + i_unreached(); + case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: + /* handle below */ + break; + case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: + if (!mail_storage_set_error_from_errno(storage)) { + mail_storage_set_critical(storage, + "save: write(%s) failed: %s", + o_stream_get_name(ctx->data.output), + o_stream_get_error(ctx->data.output)); + } + return -1; + } + if (cache_dest_mail != NULL) + index_mail_cache_parse_continue(cache_dest_mail); + + /* both tee input readers may consume data from our primary + input stream. we'll have to make sure we don't return with + one of the streams still having data in them. */ + } while (i_stream_read(input) > 0); + + if (input->stream_errno != 0) { + mail_storage_set_critical(storage, "save: read(%s) failed: %s", + i_stream_get_name(input), i_stream_get_error(input)); + return -1; + } + return 0; +} + +void index_storage_save_abort_last(struct mail_save_context *ctx, uint32_t seq) +{ + mail_index_expunge(ctx->transaction->itrans, seq); + /* currently we can't just drop pending cache updates for this one + specific record, so we'll reset the whole cache transaction. */ + mail_cache_transaction_reset(ctx->transaction->cache_trans); +} diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index be43e1d78c..d6bd1c2ad2 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -180,4 +180,9 @@ int index_storage_expunged_sync_begin(struct mailbox *box, enum mail_index_sync_flags flags); void index_storage_expunging_deinit(struct mailbox *box); +int index_storage_save_continue(struct mail_save_context *ctx, + struct istream *input, + struct mail *cache_dest_mail); +void index_storage_save_abort_last(struct mail_save_context *ctx, uint32_t seq); + #endif diff --git a/src/lib-storage/index/maildir/maildir-save.c b/src/lib-storage/index/maildir/maildir-save.c index 92c958c32a..dc4db314f4 100644 --- a/src/lib-storage/index/maildir/maildir-save.c +++ b/src/lib-storage/index/maildir/maildir-save.c @@ -512,10 +512,7 @@ static void maildir_save_remove_last_filename(struct maildir_save_context *ctx) { struct maildir_filename **fm; - mail_index_expunge(ctx->trans, ctx->seq); - /* currently we can't just drop pending cache updates for this one - specific record, so we'll reset the whole cache transaction. */ - mail_cache_transaction_reset(ctx->ctx.transaction->cache_trans); + index_storage_save_abort_last(&ctx->ctx, ctx->seq); ctx->seq--; for (fm = &ctx->files; (*fm)->next != NULL; fm = &(*fm)->next) ; diff --git a/src/lib-storage/index/mbox/mbox-save.c b/src/lib-storage/index/mbox/mbox-save.c index 95e33e829d..c67d1912ef 100644 --- a/src/lib-storage/index/mbox/mbox-save.c +++ b/src/lib-storage/index/mbox/mbox-save.c @@ -688,11 +688,7 @@ int mbox_save_finish(struct mail_save_context *_ctx) } if (ctx->seq != 0 && ctx->failed) { - mail_index_expunge(ctx->trans, ctx->seq); - /* currently we can't just drop pending cache updates for this - one specific record, so we'll reset the whole cache - transaction. */ - mail_cache_transaction_reset(ctx->ctx.transaction->cache_trans); + index_storage_save_abort_last(&ctx->ctx, ctx->seq); } index_save_context_free(_ctx); return ctx->failed ? -1 : 0;