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:
parent
37cc9f7f68
commit
b953f07500
@ -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
19
configure
vendored
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user