From: Timo Sirainen Date: Mon, 5 Aug 2013 17:27:09 +0000 (+0300) Subject: mbox: Don't use file_set_size() to grow mbox file size. X-Git-Tag: 2.2.5~8 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a97a3ce5d82b16e8979de2d6cafbf6b0a129fe4e;p=thirdparty%2Fdovecot%2Fcore.git 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. --- diff --git a/src/lib-storage/index/mbox/mbox-sync.c b/src/lib-storage/index/mbox/mbox-sync.c index 63d76fbc49..744098c148 100644 --- a/src/lib-storage/index/mbox/mbox-sync.c +++ b/src/lib-storage/index/mbox/mbox-sync.c @@ -1254,6 +1254,32 @@ static int mbox_write_pseudo(struct mbox_sync_context *sync_ctx) 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 @@ static int mbox_sync_handle_eof_updates(struct mbox_sync_context *sync_ctx, 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,