dovecot-2.0: mdbox: Don't leave partially written messages to md...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Jan 5 18:47:42 EET 2011
details: http://hg.dovecot.org/dovecot-2.0/rev/39f5ef8d612c
changeset: 12551:39f5ef8d612c
user: Timo Sirainen <tss at iki.fi>
date: Wed Jan 05 18:47:40 2011 +0200
description:
mdbox: Don't leave partially written messages to mdbox files.
diffstat:
src/lib-storage/index/dbox-common/dbox-file.c | 17 +++++++++++++++++
src/lib-storage/index/dbox-common/dbox-file.h | 5 ++++-
src/lib-storage/index/dbox-multi/mdbox-map.c | 14 +++++++++-----
src/lib-storage/index/dbox-single/sdbox-save.c | 7 +++++--
4 files changed, 35 insertions(+), 8 deletions(-)
diffs (108 lines):
diff -r b32e7bc87a09 -r 39f5ef8d612c src/lib-storage/index/dbox-common/dbox-file.c
--- 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 */
diff -r b32e7bc87a09 -r 39f5ef8d612c src/lib-storage/index/dbox-common/dbox-file.h
--- 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);
diff -r b32e7bc87a09 -r 39f5ef8d612c src/lib-storage/index/dbox-multi/mdbox-map.c
--- 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)
diff -r b32e7bc87a09 -r 39f5ef8d612c src/lib-storage/index/dbox-single/sdbox-save.c
--- 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);
More information about the dovecot-cvs
mailing list