Patchwork block/raw-posix.c: add BLKDISCARD support

login
register
mail settings
Submitter e-t172
Date Nov. 11, 2011, 8:56 p.m.
Message ID <4EBD8BE0.50908@akegroup.org>
Download mbox | patch
Permalink /patch/125298/
State New
Headers show

Comments

e-t172 - Nov. 11, 2011, 8:56 p.m.
This adds ioctl(BLKDISCARD) (a.k.a "discard", "TRIM", "UNMAP", "hole
punching") support for host devices. This is especially useful if the
raw device is a SSD or some kind of thin-provisioned device.

Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Etienne Dechamps <e-t172@akegroup.org>
---
  block/raw-posix.c |   20 ++++++++++++++++++++
  1 files changed, 20 insertions(+), 0 deletions(-)
Stefan Hajnoczi - Nov. 14, 2011, 2:08 p.m.
On Fri, Nov 11, 2011 at 8:56 PM, e-t172 <e-t172@akegroup.org> wrote:
> +static int hdev_co_discard(BlockDriverState *bs, int64_t sector_num,
> +                        int nb_sectors)
> +{
> +    BDRVRawState *s = bs->opaque;
> +    int fd = s->fd;
> +    uint64_t range[2];
> +
> +    range[0] = sector_num << 9;
> +    range[1] = nb_sectors << 9;
> +    if (ioctl(fd, BLKDISCARD, &range)) {
> +        return -errno;
> +    }
> +    return 0;
> +}

Is ioctl(BLKDISCARD) guaranteed non-blocking?  I think we need to use
paio_ioctl() here instead to do this asynchronously.

Let's also be careful about Linux-specific ioctls.  This code should
not poke an unsupported ioctl() on OSes which do not support
BLKDISCARD.  We definitely need a plan when #if !defined(__linux__).

Stefan

Patch

diff --git a/block/raw-posix.c b/block/raw-posix.c
index a3de373..d6eac66 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -104,6 +104,10 @@ 
  #define O_DIRECT O_DSYNC
  #endif

+#ifndef BLKDISCARD
+#define BLKDISCARD _IO(0x12, 119)
+#endif
+
  #define FTYPE_FILE   0
  #define FTYPE_CD     1
  #define FTYPE_FD     2
@@ -892,6 +896,21 @@  static int hdev_has_zero_init(BlockDriverState *bs)
      return 0;
  }

+static int hdev_co_discard(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors)
+{
+    BDRVRawState *s = bs->opaque;
+    int fd = s->fd;
+    uint64_t range[2];
+
+    range[0] = sector_num << 9;
+    range[1] = nb_sectors << 9;
+    if (ioctl(fd, BLKDISCARD, &range)) {
+        return -errno;
+    }
+    return 0;
+}
+
  static BlockDriver bdrv_host_device = {
      .format_name        = "host_device",
      .protocol_name        = "host_device",
@@ -902,6 +921,7 @@  static BlockDriver bdrv_host_device = {
      .bdrv_create        = hdev_create,
      .create_options     = raw_create_options,
      .bdrv_has_zero_init = hdev_has_zero_init,
+    .bdrv_co_discard       = hdev_co_discard,

      .bdrv_aio_readv    = raw_aio_readv,
      .bdrv_aio_writev   = raw_aio_writev,