]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Move backend code to a common index_storage_save_abort_last()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 28 Apr 2017 11:06:43 +0000 (14:06 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Thu, 11 May 2017 12:28:17 +0000 (15:28 +0300)
Conflicts:
src/lib-storage/index/index-storage.c
src/lib-storage/index/index-storage.h

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

index db50757cdd269b6025af9c84a3441276d91029e5..86fdb7ec261b01606af9134889b1040c40656cf5 100644 (file)
@@ -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;
index 95ff5c256c9df729261267c6cea2c10941063c77..feb2fd28c12ee2774e5ffed8e81e14a964cafe4a 100644 (file)
@@ -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);
index 1f0c070858d1299a0b45cfc666bc3ccab3083f2c..8222dc974bf8998e0a06a97cf5bf198011bedc3f 100644 (file)
@@ -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);
+}
index be43e1d78c3ea030cb325810380b9d556d4a50c8..d6bd1c2ad2c732a228a9ecd25d98a59b03b81ebd 100644 (file)
@@ -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
index 92c958c32a2d8d81c55047af908343b592e4bcce..dc4db314f40620515dfad4f0b81d2ae855b98b91 100644 (file)
@@ -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) ;
index 95e33e829df720becf6df2f1f30b2a45cd029670..c67d1912ef963d4dba7a0b7256891a2a286afb77 100644 (file)
@@ -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;