block: use fallocate(FALLOC_FL_ZERO_RANGE) in handle_aiocb_write_zeroes

This efficiently writes zeroes on Linux if the kernel is capable enough.
FALLOC_FL_ZERO_RANGE correctly handles all cases, including and not
including file expansion.

CC: Kevin Wolf <kwolf@redhat.com>
CC: Stefan Hajnoczi <stefanha@redhat.com>
CC: Peter Lieven <pl@kamp.de>
CC: Fam Zheng <famz@redhat.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Denis V. Lunev 2015-01-30 11:42:14 +03:00 committed by Kevin Wolf
parent 37cc9f7f68
commit b953f07500
2 changed files with 32 additions and 2 deletions

View File

@ -60,7 +60,7 @@
#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
#endif
#endif
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_FALLOCATE_ZERO_RANGE)
#include <linux/falloc.h>
#endif
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
@ -902,7 +902,7 @@ static int translate_err(int err)
return err;
}
#if defined(CONFIG_FALLOCATE_PUNCH_HOLE)
#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_FALLOCATE_ZERO_RANGE)
static int do_fallocate(int fd, int mode, off_t offset, off_t len)
{
do {
@ -954,6 +954,17 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
}
#endif
#ifdef CONFIG_FALLOCATE_ZERO_RANGE
if (s->has_write_zeroes) {
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
aiocb->aio_offset, aiocb->aio_nbytes);
if (ret == 0 || ret != -ENOTSUP) {
return ret;
}
s->has_write_zeroes = false;
}
#endif
return -ENOTSUP;
}

19
configure vendored
View File

@ -3335,6 +3335,22 @@ if compile_prog "" "" ; then
fallocate_punch_hole=yes
fi
# check that fallocate supports range zeroing inside the file
fallocate_zero_range=no
cat > $TMPC << EOF
#include <fcntl.h>
#include <linux/falloc.h>
int main(void)
{
fallocate(0, FALLOC_FL_ZERO_RANGE, 0, 0);
return 0;
}
EOF
if compile_prog "" "" ; then
fallocate_zero_range=yes
fi
# check for posix_fallocate
posix_fallocate=no
cat > $TMPC << EOF
@ -4567,6 +4583,9 @@ fi
if test "$fallocate_punch_hole" = "yes" ; then
echo "CONFIG_FALLOCATE_PUNCH_HOLE=y" >> $config_host_mak
fi
if test "$fallocate_zero_range" = "yes" ; then
echo "CONFIG_FALLOCATE_ZERO_RANGE=y" >> $config_host_mak
fi
if test "$posix_fallocate" = "yes" ; then
echo "CONFIG_POSIX_FALLOCATE=y" >> $config_host_mak
fi