Patchwork [03/12] block: introduce BDRV_REQ_MAY_UNMAP in bdrv_co_write_zeroes

login
register
mail settings
Submitter Peter Lieven
Date Sept. 13, 2013, 10:25 a.m.
Message ID <1379067909-22984-4-git-send-email-pl@kamp.de>
Download mbox | patch
Permalink /patch/274711/
State New
Headers show

Comments

Peter Lieven - Sept. 13, 2013, 10:25 a.m.
the BDRV_REQ_MAY_UNMAP flag is used to indicate that block driver
is allowed to optimze a write zeroes request by unmapping (discarding)
blocks if it is guaranteed that the result will read back as
zeroes.

the flag is only passed to the driver if the block device is
opened with BDRV_O_UNMAP.

Signed-off-by: Peter Lieven <pl@kamp.de>
---
 block-migration.c     |    3 ++-
 block.c               |    4 ++++
 block/backup.c        |    2 +-
 include/block/block.h |    1 +
 4 files changed, 8 insertions(+), 2 deletions(-)
Eric Blake - Sept. 13, 2013, 6:07 p.m.
On 09/13/2013 04:25 AM, Peter Lieven wrote:
> the BDRV_REQ_MAY_UNMAP flag is used to indicate that block driver
> is allowed to optimze a write zeroes request by unmapping (discarding)

s/optimze/optimize/

> blocks if it is guaranteed that the result will read back as
> zeroes.
> 
> the flag is only passed to the driver if the block device is
> opened with BDRV_O_UNMAP.
> 
> Signed-off-by: Peter Lieven <pl@kamp.de>
> ---

> +++ b/include/block/block.h
> @@ -65,6 +65,7 @@ typedef struct BlockDevOps {
>  typedef enum {
>      BDRV_REQ_COPY_ON_READ = 0x1,
>      BDRV_REQ_ZERO_WRITE   = 0x2,
> +    BDRV_REQ_MAY_UNMAP    = 0x4,

Now that this enum is public, it would be useful to have inline
documentation, rather than making people dig up the git history of when
it was introduced to learn its semantics.

Patch

diff --git a/block-migration.c b/block-migration.c
index 713a8e3..fc4ef93 100644
--- a/block-migration.c
+++ b/block-migration.c
@@ -780,7 +780,8 @@  static int block_load(QEMUFile *f, void *opaque, int version_id)
             }
 
             if (flags & BLK_MIG_FLAG_ZERO_BLOCK) {
-                ret = bdrv_write_zeroes(bs, addr, nr_sectors, 0);
+                ret = bdrv_write_zeroes(bs, addr, nr_sectors,
+                                        BDRV_REQ_MAY_UNMAP);
             } else {
                 buf = g_malloc(BLOCK_SIZE);
                 qemu_get_buffer(f, buf, BLOCK_SIZE);
diff --git a/block.c b/block.c
index e5918a7..6f498fc 100644
--- a/block.c
+++ b/block.c
@@ -2761,6 +2761,10 @@  int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs,
 {
     trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors);
 
+    if (!(bs->open_flags & BDRV_O_UNMAP)) {
+        flags &= ~BDRV_REQ_MAY_UNMAP;
+    }
+
     return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL,
                              BDRV_REQ_ZERO_WRITE | flags);
 }
diff --git a/block/backup.c b/block/backup.c
index 5f6a642..1ab080d 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -139,7 +139,7 @@  static int coroutine_fn backup_do_cow(BlockDriverState *bs,
         if (buffer_is_zero(iov.iov_base, iov.iov_len)) {
             ret = bdrv_co_write_zeroes(job->target,
                                        start * BACKUP_SECTORS_PER_CLUSTER,
-                                       n, 0);
+                                       n, BDRV_REQ_MAY_UNMAP);
         } else {
             ret = bdrv_co_writev(job->target,
                                  start * BACKUP_SECTORS_PER_CLUSTER, n,
diff --git a/include/block/block.h b/include/block/block.h
index ddb6870..599de7d 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -65,6 +65,7 @@  typedef struct BlockDevOps {
 typedef enum {
     BDRV_REQ_COPY_ON_READ = 0x1,
     BDRV_REQ_ZERO_WRITE   = 0x2,
+    BDRV_REQ_MAY_UNMAP    = 0x4,
 } BdrvRequestFlags;
 
 #define BDRV_O_RDWR        0x0002