Mercurial > dovecot > core-2.2
changeset 12686:39f5ef8d612c
mdbox: Don't leave partially written messages to mdbox files.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 05 Jan 2011 18:47:40 +0200 |
parents | b32e7bc87a09 |
children | 7bdd06de6f5a |
files | src/lib-storage/index/dbox-common/dbox-file.c src/lib-storage/index/dbox-common/dbox-file.h src/lib-storage/index/dbox-multi/mdbox-map.c src/lib-storage/index/dbox-single/sdbox-save.c |
diffstat | 4 files changed, 35 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox-common/dbox-file.c Wed Jan 05 18:11:04 2011 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-file.c Wed Jan 05 18:47:40 2011 +0200 @@ -479,6 +479,13 @@ *_ctx = NULL; ret = dbox_file_append_flush(ctx); + if (ctx->last_checkpoint_offset != ctx->output->offset) { + o_stream_close(ctx->output); + if (ftruncate(ctx->file->fd, ctx->last_checkpoint_offset) < 0) { + dbox_file_set_syscall_error(ctx->file, "ftruncate()"); + return -1; + } + } o_stream_unref(&ctx->output); ctx->file->appending = FALSE; i_free(ctx); @@ -538,6 +545,11 @@ return 0; } +void dbox_file_append_checkpoint(struct dbox_file_append_context *ctx) +{ + ctx->last_checkpoint_offset = ctx->output->offset; +} + int dbox_file_get_append_stream(struct dbox_file_append_context *ctx, struct ostream **output_r) { @@ -548,6 +560,11 @@ /* file creation had failed */ return -1; } + if (ctx->last_checkpoint_offset != ctx->output->offset) { + /* a message was aborted. don't try appending to this + file anymore. */ + return -1; + } if (file->file_version == 0) { /* newly created file, write the file header */
--- a/src/lib-storage/index/dbox-common/dbox-file.h Wed Jan 05 18:11:04 2011 +0200 +++ b/src/lib-storage/index/dbox-common/dbox-file.h Wed Jan 05 18:47:40 2011 +0200 @@ -126,7 +126,7 @@ struct dbox_file_append_context { struct dbox_file *file; - uoff_t first_append_offset, last_flush_offset; + uoff_t first_append_offset, last_checkpoint_offset, last_flush_offset; struct ostream *output; }; @@ -173,6 +173,9 @@ can't be appended to (old file version or corruption) or -1 if error. */ int dbox_file_get_append_stream(struct dbox_file_append_context *ctx, struct ostream **output_r); +/* Call after message has been fully saved. If this isn't done, the writes + since the last checkpoint are truncated. */ +void dbox_file_append_checkpoint(struct dbox_file_append_context *ctx); /* Flush output buffer. */ int dbox_file_append_flush(struct dbox_file_append_context *ctx);
--- a/src/lib-storage/index/dbox-multi/mdbox-map.c Wed Jan 05 18:11:04 2011 +0200 +++ b/src/lib-storage/index/dbox-multi/mdbox-map.c Wed Jan 05 18:47:40 2011 +0200 @@ -1097,15 +1097,19 @@ void mdbox_map_append_finish(struct mdbox_map_append_context *ctx) { - struct mdbox_map_append *appends; + struct mdbox_map_append *appends, *last; unsigned int count; uoff_t cur_offset; appends = array_get_modifiable(&ctx->appends, &count); - i_assert(count > 0 && appends[count-1].size == (uint32_t)-1); - cur_offset = appends[count-1].file_append->output->offset; - i_assert(cur_offset >= appends[count-1].offset); - appends[count-1].size = cur_offset - appends[count-1].offset; + i_assert(count > 0); + last = &appends[count-1]; + i_assert(last->size == (uint32_t)-1); + + cur_offset = last->file_append->output->offset; + i_assert(cur_offset >= last->offset); + last->size = cur_offset - last->offset; + dbox_file_append_checkpoint(last->file_append); } void mdbox_map_append_abort(struct mdbox_map_append_context *ctx)
--- a/src/lib-storage/index/dbox-single/sdbox-save.c Wed Jan 05 18:11:04 2011 +0200 +++ b/src/lib-storage/index/dbox-single/sdbox-save.c Wed Jan 05 18:47:40 2011 +0200 @@ -186,8 +186,11 @@ if (ctx->ctx.failed) dbox_file_append_rollback(&ctx->append_ctx); - else if (dbox_file_append_commit(&ctx->append_ctx) < 0) - ctx->ctx.failed = TRUE; + else { + dbox_file_append_checkpoint(ctx->append_ctx); + if (dbox_file_append_commit(&ctx->append_ctx) < 0) + ctx->ctx.failed = TRUE; + } i_stream_unref(&ctx->ctx.input); dbox_file_close(*files);