changeset 22012:ce5fc3bd3b40

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
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 28 Apr 2017 14:06:43 +0300
parents 98d9d2f12593
children b57e0cfd334d
files src/lib-storage/index/dbox-multi/mdbox-save.c src/lib-storage/index/dbox-single/sdbox-save.c src/lib-storage/index/index-storage.c src/lib-storage/index/index-storage.h src/lib-storage/index/maildir/maildir-save.c src/lib-storage/index/mbox/mbox-save.c
diffstat 6 files changed, 59 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-multi/mdbox-save.c	Thu Apr 27 14:09:08 2017 +0300
+++ b/src/lib-storage/index/dbox-multi/mdbox-save.c	Fri Apr 28 14:06:43 2017 +0300
@@ -216,8 +216,7 @@
 	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;
--- a/src/lib-storage/index/dbox-single/sdbox-save.c	Thu Apr 27 14:09:08 2017 +0300
+++ b/src/lib-storage/index/dbox-single/sdbox-save.c	Fri Apr 28 14:06:43 2017 +0300
@@ -195,8 +195,7 @@
 	} 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);
--- a/src/lib-storage/index/index-storage.c	Thu Apr 27 14:09:08 2017 +0300
+++ b/src/lib-storage/index/index-storage.c	Fri Apr 28 14:06:43 2017 +0300
@@ -1072,3 +1072,53 @@
 	}
 	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);
+}
--- a/src/lib-storage/index/index-storage.h	Thu Apr 27 14:09:08 2017 +0300
+++ b/src/lib-storage/index/index-storage.h	Fri Apr 28 14:06:43 2017 +0300
@@ -180,4 +180,9 @@
 				      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
--- a/src/lib-storage/index/maildir/maildir-save.c	Thu Apr 27 14:09:08 2017 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c	Fri Apr 28 14:06:43 2017 +0300
@@ -512,10 +512,7 @@
 {
 	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) ;
--- a/src/lib-storage/index/mbox/mbox-save.c	Thu Apr 27 14:09:08 2017 +0300
+++ b/src/lib-storage/index/mbox/mbox-save.c	Fri Apr 28 14:06:43 2017 +0300
@@ -688,11 +688,7 @@
 	}
 
 	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;