diff mbox

[2/2] block: use fallocate(FALLOC_FL_PUNCH_HOLE) & fallocate(0) to write zeroes

Message ID 1419485850-21455-3-git-send-email-den@openvz.org
State New
Headers show

Commit Message

Denis V. Lunev Dec. 25, 2014, 5:37 a.m. UTC
This sequence works efficiently if FALLOC_FL_ZERO_RANGE is not supported.
The idea is that FALLOC_FL_PUNCH_HOLE could not increase file size
but it cleans already allocated blocks inside the file. If we have to
create something new, simple fallocate will do the job.

This should increase performance a bit for not-so-modern kernels or for
filesystems which do not support FALLOC_FL_ZERO_RANGE.

Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
---
 block/raw-posix.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

Comments

Roman Kagan Dec. 26, 2014, 9:25 a.m. UTC | #1
On Thu, Dec 25, 2014 at 08:37:30AM +0300, Denis V. Lunev wrote:
> This sequence works efficiently if FALLOC_FL_ZERO_RANGE is not supported.
> The idea is that FALLOC_FL_PUNCH_HOLE could not increase file size
> but it cleans already allocated blocks inside the file. If we have to
> create something new, simple fallocate will do the job.
> 
> This should increase performance a bit for not-so-modern kernels or for
> filesystems which do not support FALLOC_FL_ZERO_RANGE.
> 
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Kevin Wolf <kwolf@redhat.com>
> CC: Stefan Hajnoczi <stefanha@redhat.com>
> ---
>  block/raw-posix.c | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/block/raw-posix.c b/block/raw-posix.c
> index 9e66cb7..60972a1 100644
> --- a/block/raw-posix.c
> +++ b/block/raw-posix.c
> @@ -930,6 +930,18 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
>  
>          ret = -errno;
>  #endif
> +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
> +        do {
> +            if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
> +                          aiocb->aio_offset, aiocb->aio_nbytes) == 0 &&
> +                fallocate(s->fd, 0,
> +                          aiocb->aio_offset, aiocb->aio_nbytes) == 0) {
> +                return 0;
> +            }
> +        } while (errno == EINTR);
> +
> +        ret = -errno;
> +#endif

This is suboptimal in that fallocate(FALLOC_FL_ZERO_RANGE) would always
be called in vain for such systems.  Might be worth another flag in
BDRVRawState?

Roman.
diff mbox

Patch

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 9e66cb7..60972a1 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -930,6 +930,18 @@  static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
 
         ret = -errno;
 #endif
+#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
+        do {
+            if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
+                          aiocb->aio_offset, aiocb->aio_nbytes) == 0 &&
+                fallocate(s->fd, 0,
+                          aiocb->aio_offset, aiocb->aio_nbytes) == 0) {
+                return 0;
+            }
+        } while (errno == EINTR);
+
+        ret = -errno;
+#endif
     }
 
     if (ret == -ENODEV || ret == -ENOSYS || ret == -EOPNOTSUPP ||