dovecot-2.2: mbox: Don't use file_set_size() to grow mbox file s...

dovecot at dovecot.org dovecot at dovecot.org
Mon Aug 5 20:27:17 EEST 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/42b2736f146b
changeset: 16651:42b2736f146b
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Aug 05 20:27:09 2013 +0300
description:
mbox: Don't use file_set_size() to grow mbox file size.
posix_fallocate() apparently grows file size in 4kB blocks in GFS2 causing
extra NULs to be written. The mbox file rarely needs to grow so much that
there's any point in using any optimizations for it.

Besides, this was the last place where file_set_size() was used. If no
further use can be found for it, it could be removed entirely.

diffstat:

 src/lib-storage/index/mbox/mbox-sync.c |  37 +++++++++++++++++++++++++--------
 1 files changed, 28 insertions(+), 9 deletions(-)

diffs (55 lines):

diff -r 1adb8998c2a6 -r 42b2736f146b src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c	Mon Aug 05 20:12:10 2013 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Mon Aug 05 20:27:09 2013 +0300
@@ -1254,6 +1254,32 @@
 	return 0;
 }
 
+static int mbox_append_zero(struct mbox_sync_context *sync_ctx,
+			    uoff_t orig_file_size, uoff_t count)
+{
+	char block[IO_BLOCK_SIZE];
+	uoff_t offset = orig_file_size;
+	ssize_t ret = 0;
+
+	memset(block, 0, I_MIN(sizeof(block), count));
+	while (count > 0) {
+		ret = pwrite(sync_ctx->write_fd, block,
+			     I_MIN(sizeof(block), count), offset);
+		if (ret < 0)
+			break;
+		offset += ret;
+		count -= ret;
+	}
+
+	if (ret < 0) {
+		mbox_set_syscall_error(sync_ctx->mbox, "pwrite()");
+		if (ftruncate(sync_ctx->write_fd, orig_file_size) < 0)
+			mbox_set_syscall_error(sync_ctx->mbox, "ftruncate()");
+		return -1;
+	}
+	return 0;
+}
+
 static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx,
 					struct mbox_sync_mail_context *mail_ctx)
 {
@@ -1303,16 +1329,9 @@
 
 		i_assert(sync_ctx->space_diff < 0);
 
-		if (file_set_size(sync_ctx->write_fd,
-				  file_size + -sync_ctx->space_diff) < 0) {
-			mbox_set_syscall_error(sync_ctx->mbox,
-					       "file_set_size()");
-			if (ftruncate(sync_ctx->write_fd, file_size) < 0) {
-				mbox_set_syscall_error(sync_ctx->mbox,
-						       "ftruncate()");
-			}
+		if (mbox_append_zero(sync_ctx, file_size,
+				     -sync_ctx->space_diff) < 0)
 			return -1;
-		}
 		mbox_sync_file_updated(sync_ctx, FALSE);
 
 		if (mbox_sync_rewrite(sync_ctx, mail_ctx, file_size,


More information about the dovecot-cvs mailing list