changeset 16651:42b2736f146b

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.
author Timo Sirainen <tss@iki.fi>
date Mon, 05 Aug 2013 20:27:09 +0300
parents 1adb8998c2a6
children 556475a5c1be
files src/lib-storage/index/mbox/mbox-sync.c
diffstat 1 files changed, 28 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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,