From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:33010) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tv9h2-0002HZ-Qh for qemu-devel@nongnu.org; Tue, 15 Jan 2013 11:49:00 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Tv9gz-0005Xr-S8 for qemu-devel@nongnu.org; Tue, 15 Jan 2013 11:48:56 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41252) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Tv9gz-0005Xk-Jd for qemu-devel@nongnu.org; Tue, 15 Jan 2013 11:48:53 -0500 From: Stefan Hajnoczi Date: Tue, 15 Jan 2013 17:48:19 +0100 Message-Id: <1358268511-27061-4-git-send-email-stefanha@redhat.com> In-Reply-To: <1358268511-27061-1-git-send-email-stefanha@redhat.com> References: <1358268511-27061-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PATCH 03/15] raw-posix: support discard on more filesystems List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori , Kusanagi Kouichi , Stefan Hajnoczi From: Kusanagi Kouichi Linux 2.6.38 introduced the filesystem independent interface to deallocate part of a file. As of Linux 3.7, btrfs, ext4, ocfs2, tmpfs and xfs support it. Even though the system calls here are in practice issued on Linux, the code is structured to allow plugging in alternatives for other Unix variants. EOPNOTSUPP is used unconditionally in this patch, but it is supported in both OpenBSD and Mac OS X since forever (see for example http://lists.debian.org/debian-glibc/2006/02/msg00337.html). Signed-off-by: Kusanagi Kouichi Signed-off-by: Stefan Hajnoczi --- block/raw-posix.c | 26 ++++++++++++++++++++++++-- configure | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/block/raw-posix.c b/block/raw-posix.c index c3d7fda..e8d79af 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -59,6 +59,9 @@ #ifdef CONFIG_FIEMAP #include #endif +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE +#include +#endif #if defined (__FreeBSD__) || defined(__FreeBSD_kernel__) #include #include @@ -1074,15 +1077,34 @@ static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors) static coroutine_fn int raw_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors) { -#ifdef CONFIG_XFS + int ret = -EOPNOTSUPP; + +#if defined(CONFIG_FALLOCATE_PUNCH_HOLE) || defined(CONFIG_XFS) BDRVRawState *s = bs->opaque; +#ifdef CONFIG_XFS if (s->is_xfs) { return xfs_discard(s, sector_num, nb_sectors); } #endif - return 0; +#ifdef CONFIG_FALLOCATE_PUNCH_HOLE + do { + if (fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, + sector_num << BDRV_SECTOR_BITS, + (int64_t)nb_sectors << BDRV_SECTOR_BITS) == 0) { + return 0; + } + } while (errno == EINTR); + + ret = -errno; +#endif +#endif + + if (ret == -EOPNOTSUPP) { + return 0; + } + return ret; } static QEMUOptionParameter raw_create_options[] = { diff --git a/configure b/configure index c908f66..40d250c 100755 --- a/configure +++ b/configure @@ -2581,6 +2581,22 @@ if compile_prog "" "" ; then fallocate=yes fi +# check for fallocate hole punching +fallocate_punch_hole=no +cat > $TMPC << EOF +#include +#include + +int main(void) +{ + fallocate(0, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, 0, 0); + return 0; +} +EOF +if compile_prog "" "" ; then + fallocate_punch_hole=yes +fi + # check for sync_file_range sync_file_range=no cat > $TMPC << EOF @@ -3490,6 +3506,9 @@ fi if test "$fallocate" = "yes" ; then echo "CONFIG_FALLOCATE=y" >> $config_host_mak fi +if test "$fallocate_punch_hole" = "yes" ; then + echo "CONFIG_FALLOCATE_PUNCH_HOLE=y" >> $config_host_mak +fi if test "$sync_file_range" = "yes" ; then echo "CONFIG_SYNC_FILE_RANGE=y" >> $config_host_mak fi -- 1.8.0.2