]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mbox: Don't use file_set_size() to grow mbox file size.
authorTimo Sirainen <tss@iki.fi>
Mon, 5 Aug 2013 17:27:09 +0000 (20:27 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 5 Aug 2013 17:27:09 +0000 (20:27 +0300)
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.

src/lib-storage/index/mbox/mbox-sync.c

index 63d76fbc49d2f79564938c41962b3970e2e71eea..744098c14817b2b708b20e426ae72e83456631ce 100644 (file)
@@ -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,