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