Commit dce512de authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Kevin Wolf
Browse files

raw-posix: add discard support



Add support to discard blocks in a raw image residing on an XFS filesystem
by calling the XFS_IOC_UNRESVSP64 ioctl to punch holes.  Support for other
hole punching mechanisms can be added when they become available.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent edff5db1
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -69,6 +69,10 @@
#include <sys/diskslice.h>
#endif

#ifdef CONFIG_XFS
#include <xfs/xfs.h>
#endif

//#define DEBUG_FLOPPY

//#define DEBUG_BLOCK
@@ -120,6 +124,9 @@ typedef struct BDRVRawState {
#endif
    uint8_t *aligned_buf;
    unsigned aligned_buf_size;
#ifdef CONFIG_XFS
    bool is_xfs : 1;
#endif
} BDRVRawState;

static int fd_open(BlockDriverState *bs);
@@ -196,6 +203,12 @@ static int raw_open_common(BlockDriverState *bs, const char *filename,
#endif
    }

#ifdef CONFIG_XFS
    if (platform_test_xfs_fd(s->fd)) {
        s->is_xfs = 1;
    }
#endif

    return 0;

out_free_buf:
@@ -740,6 +753,37 @@ static int raw_flush(BlockDriverState *bs)
    return qemu_fdatasync(s->fd);
}

#ifdef CONFIG_XFS
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
{
    struct xfs_flock64 fl;

    memset(&fl, 0, sizeof(fl));
    fl.l_whence = SEEK_SET;
    fl.l_start = sector_num << 9;
    fl.l_len = (int64_t)nb_sectors << 9;

    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
        DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
        return -errno;
    }

    return 0;
}
#endif

static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
{
#ifdef CONFIG_XFS
    BDRVRawState *s = bs->opaque;

    if (s->is_xfs) {
        return xfs_discard(s, sector_num, nb_sectors);
    }
#endif

    return 0;
}

static QEMUOptionParameter raw_create_options[] = {
    {
@@ -761,6 +805,7 @@ static BlockDriver bdrv_file = {
    .bdrv_close = raw_close,
    .bdrv_create = raw_create,
    .bdrv_flush = raw_flush,
    .bdrv_discard = raw_discard,

    .bdrv_aio_readv = raw_aio_readv,
    .bdrv_aio_writev = raw_aio_writev,
+26 −0
Original line number Diff line number Diff line
@@ -288,6 +288,7 @@ xen=""
linux_aio=""
attr=""
vhost_net=""
xfs=""

gprof="no"
debug_tcg="no"
@@ -1398,6 +1399,27 @@ EOF
  fi
fi

##########################################
# xfsctl() probe, used for raw-posix
if test "$xfs" != "no" ; then
  cat > $TMPC << EOF
#include <xfs/xfs.h>
int main(void)
{
    xfsctl(NULL, 0, 0, NULL);
    return 0;
}
EOF
  if compile_prog "" "" ; then
    xfs="yes"
  else
    if test "$xfs" = "yes" ; then
      feature_not_found "xfs"
    fi
    xfs=no
  fi
fi

##########################################
# vde libraries probe
if test "$vde" != "no" ; then
@@ -2403,6 +2425,7 @@ echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "spice support     $spice"
echo "rbd support       $rbd"
echo "xfsctl support    $xfs"

if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have SDL support"
@@ -2548,6 +2571,9 @@ fi
if test "$uuid" = "yes" ; then
  echo "CONFIG_UUID=y" >> $config_host_mak
fi
if test "$xfs" = "yes" ; then
  echo "CONFIG_XFS=y" >> $config_host_mak
fi
qemu_version=`head $source_path/VERSION`
echo "VERSION=$qemu_version" >>$config_host_mak
echo "PKGVERSION=$pkgversion" >>$config_host_mak