All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks
@ 2017-09-14 14:40 Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 01/20] block: Add .bdrv_co_block_status() callback Eric Blake
                   ` (19 more replies)
  0 siblings, 20 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block

There are patches floating around to add NBD_CMD_BLOCK_STATUS,
but NBD wants to report status on byte granularity (even if the
reporting will probably be naturally aligned to sectors or even
much higher levels).  I've therefore started the task of
converting our block status code to report at a byte granularity
rather than sectors.

Now that 2.11 is open, I'm rebasing/reposting the remaining patches.

The overall conversion currently looks like:
part 1: bdrv_is_allocated (merged, commit 51b0a488)
part 2: dirty-bitmap (v7 is posted [1], mostly reviewed, but may need v8)
part 3: bdrv_get_block_status (v4 is posted [2], partially reviewed)
part 4: .bdrv_co_block_status (this series, v2 was here [3])

Available as a tag at:
git fetch git://repo.or.cz/qemu/ericb.git nbd-byte-status-v4

Based-on: <20170912203119.24166-1-eblake@redhat.com>
([PATCH v7 00/20] make dirty-bitmap byte-based)

Based-on: <20170914134923.2479-1-eblake@redhat.com>
([PATCH v2] osdep: Fix ROUND_UP(64-bit, 32-bit))

Based-on: <20170913160333.23622-1-eblake@redhat.com>
([PATCH v4 00/24] make bdrv_get_block_status byte-based)

[1] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg03160.html
[2] https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg03543.html
[3] https://lists.gnu.org/archive/html/qemu-devel/2017-07/msg04370.html

Diff from v2:
- Minor rebasing

001/20:[----] [--] 'block: Add .bdrv_co_block_status() callback'
002/20:[0002] [FC] 'block: Switch passthrough drivers to .bdrv_co_block_status()'
003/20:[----] [--] 'file-posix: Switch to .bdrv_co_block_status()'
004/20:[----] [--] 'gluster: Switch to .bdrv_co_block_status()'
005/20:[----] [--] 'iscsi: Switch cluster_sectors to byte-based'
006/20:[----] [--] 'iscsi: Switch iscsi_allocmap_update() to byte-based'
007/20:[----] [--] 'iscsi: Switch to .bdrv_co_block_status()'
008/20:[----] [--] 'null: Switch to .bdrv_co_block_status()'
009/20:[----] [--] 'parallels: Switch to .bdrv_co_block_status()'
010/20:[0008] [FC] 'qcow: Switch to .bdrv_co_block_status()'
011/20:[----] [--] 'qcow2: Switch to .bdrv_co_block_status()'
012/20:[----] [--] 'qed: Switch to .bdrv_co_block_status()'
013/20:[----] [--] 'raw: Switch to .bdrv_co_block_status()'
014/20:[----] [--] 'sheepdog: Switch to .bdrv_co_block_status()'
015/20:[----] [--] 'vdi: Avoid bitrot of debugging code'
016/20:[----] [--] 'vdi: Switch to .bdrv_co_block_status()'
017/20:[----] [--] 'vmdk: Switch to .bdrv_co_block_status()'
018/20:[0015] [FC] 'vpc: Switch to .bdrv_co_block_status()'
019/20:[----] [--] 'vvfat: Switch to .bdrv_co_block_status()'
020/20:[----] [--] 'block: Drop unused .bdrv_co_get_block_status()'

Eric Blake (20):
  block: Add .bdrv_co_block_status() callback
  block: Switch passthrough drivers to .bdrv_co_block_status()
  file-posix: Switch to .bdrv_co_block_status()
  gluster: Switch to .bdrv_co_block_status()
  iscsi: Switch cluster_sectors to byte-based
  iscsi: Switch iscsi_allocmap_update() to byte-based
  iscsi: Switch to .bdrv_co_block_status()
  null: Switch to .bdrv_co_block_status()
  parallels: Switch to .bdrv_co_block_status()
  qcow: Switch to .bdrv_co_block_status()
  qcow2: Switch to .bdrv_co_block_status()
  qed: Switch to .bdrv_co_block_status()
  raw: Switch to .bdrv_co_block_status()
  sheepdog: Switch to .bdrv_co_block_status()
  vdi: Avoid bitrot of debugging code
  vdi: Switch to .bdrv_co_block_status()
  vmdk: Switch to .bdrv_co_block_status()
  vpc: Switch to .bdrv_co_block_status()
  vvfat: Switch to .bdrv_co_block_status()
  block: Drop unused .bdrv_co_get_block_status()

 include/block/block_int.h |  38 ++++++------
 block/io.c                |  60 ++++++++++---------
 block/blkdebug.c          |  19 +++---
 block/commit.c            |   2 +-
 block/file-posix.c        |  57 ++++++++++--------
 block/gluster.c           |  62 +++++++++++---------
 block/iscsi.c             | 146 +++++++++++++++++++++++++---------------------
 block/mirror.c            |   2 +-
 block/null.c              |  22 +++----
 block/parallels.c         |  19 ++++--
 block/qcow.c              |  25 ++++----
 block/qcow2.c             |  21 ++++---
 block/qed.c               |  22 +++----
 block/raw-format.c        |  17 +++---
 block/sheepdog.c          |  23 ++++----
 block/throttle.c          |   2 +-
 block/vdi.c               |  40 ++++++-------
 block/vmdk.c              |  27 +++++----
 block/vpc.c               |  35 +++++------
 block/vvfat.c             |  16 +++--
 20 files changed, 350 insertions(+), 305 deletions(-)

-- 
2.13.5

^ permalink raw reply	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 01/20] block: Add .bdrv_co_block_status() callback
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 02/20] block: Switch passthrough drivers to .bdrv_co_block_status() Eric Blake
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Stefan Hajnoczi, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based. Now that the block layer exposes byte-based allocation,
it's time to tackle the drivers.  Add a new callback that operates
on as small as byte boundaries. Subsequent patches will then update
individual drivers, then finally remove .bdrv_co_get_block_status().
The old code now uses a goto in order to minimize churn at that later
removal.

The new code also passes through the 'mapping' hint, which will
allow subsequent patches to further optimize callers that only care
about how much of the image is allocated, rather than which offsets
the allocation actually maps to.

Note that most drivers give sector-aligned answers, except at
end-of-file, even when request_alignment is smaller than a sector.
However, bdrv_getlength() is sector-aligned (even though it gives a
byte answer), often by exceeding the actual file size.  If we were to
give back strict results, at least file-posix.c would report a
transition from DATA to HOLE at the end of a file even in the middle
of a sector, which can throw off callers; so we intentionally lie and
state that any partial sector at the end of a file has the same
status for the entire sector.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: improve alignment handling, ensure all iotests still pass
---
 include/block/block_int.h | 11 ++++++++---
 block/io.c                | 27 ++++++++++++++++++++++++---
 2 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/include/block/block_int.h b/include/block/block_int.h
index b1ceffba78..0ba57dc35c 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -206,13 +206,18 @@ struct BlockDriver {
      * bdrv_is_allocated[_above].  The driver should answer only
      * according to the current layer, and should not set
      * BDRV_BLOCK_ALLOCATED, but may set BDRV_BLOCK_RAW.  See block.h
-     * for the meaning of _DATA, _ZERO, and _OFFSET_VALID.  The block
-     * layer guarantees input aligned to request_alignment, as well as
-     * non-NULL pnum and file.
+     * for the meaning of _DATA, _ZERO, and _OFFSET_VALID.  As a hint,
+     * the flag mapping is true if the caller cares more about precise
+     * mappings (favor _OFFSET_VALID) or false for overall allocation
+     * (favor larger *pnum).  The block layer guarantees input aligned
+     * to request_alignment, as well as non-NULL pnum and file.
      */
     int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, int *pnum,
         BlockDriverState **file);
+    int64_t coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bd,
+        bool mapping, int64_t offset, int64_t bytes, int64_t *pnum,
+        BlockDriverState **file);

     /*
      * Invalidate any cached meta-data.
diff --git a/block/io.c b/block/io.c
index e0f9bca7e2..4fb544d25c 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1794,7 +1794,7 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
         bytes = n;
     }

-    if (!bs->drv->bdrv_co_get_block_status) {
+    if (!bs->drv->bdrv_co_get_block_status && !bs->drv->bdrv_co_block_status) {
         *pnum = bytes;
         ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
         if (offset + bytes == total_size) {
@@ -1814,11 +1814,14 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
     bdrv_inc_in_flight(bs);

     /* Round out to request_alignment boundaries */
-    align = MAX(bs->bl.request_alignment, BDRV_SECTOR_SIZE);
+    align = bs->bl.request_alignment;
+    if (bs->drv->bdrv_co_get_block_status && align < BDRV_SECTOR_SIZE) {
+        align = BDRV_SECTOR_SIZE;
+    }
     aligned_offset = QEMU_ALIGN_DOWN(offset, align);
     aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;

-    {
+    if (bs->drv->bdrv_co_get_block_status) {
         int count; /* sectors */

         assert(QEMU_IS_ALIGNED(aligned_offset | aligned_bytes,
@@ -1832,8 +1835,26 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
             goto out;
         }
         *pnum = count * BDRV_SECTOR_SIZE;
+        goto refine;
     }

+    ret = bs->drv->bdrv_co_block_status(bs, mapping, aligned_offset,
+                                        aligned_bytes, pnum, &local_file);
+    if (ret < 0) {
+        *pnum = 0;
+        goto out;
+    }
+
+    /*
+     * total_size is always sector-aligned, by sometimes exceeding actual
+     * file size. Expand pnum if it lands mid-sector due to end-of-file.
+     */
+    if (QEMU_ALIGN_UP(*pnum + aligned_offset,
+                      BDRV_SECTOR_SIZE) == total_size) {
+        *pnum = total_size - aligned_offset;
+    }
+
+ refine:
     /* Clamp pnum and ret to original request */
     assert(QEMU_IS_ALIGNED(*pnum, align));
     *pnum -= offset - aligned_offset;
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 02/20] block: Switch passthrough drivers to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 01/20] block: Add .bdrv_co_block_status() callback Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 03/20] file-posix: Switch " Eric Blake
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, jsnow, famz, qemu-block, Max Reitz, Jeff Cody, Stefan Hajnoczi

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the generic helpers, and all passthrough clients
(blkdebug, commit, mirror, throttle) accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v3: rebase to addition of throttle driver
v2: rebase to master, retitle while merging blkdebug, commit, and mirror
---
 include/block/block_int.h | 26 ++++++++++++++------------
 block/io.c                | 30 ++++++++++++++++--------------
 block/blkdebug.c          | 19 ++++++++++---------
 block/commit.c            |  2 +-
 block/mirror.c            |  2 +-
 block/throttle.c          |  2 +-
 6 files changed, 43 insertions(+), 38 deletions(-)

diff --git a/include/block/block_int.h b/include/block/block_int.h
index 0ba57dc35c..ba5c2f9f1f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -1004,23 +1004,25 @@ void bdrv_format_default_perms(BlockDriverState *bs, BdrvChild *c,
                                uint64_t *nperm, uint64_t *nshared);

 /*
- * Default implementation for drivers to pass bdrv_co_get_block_status() to
+ * Default implementation for drivers to pass bdrv_co_block_status() to
  * their file.
  */
-int64_t coroutine_fn bdrv_co_get_block_status_from_file(BlockDriverState *bs,
-                                                        int64_t sector_num,
-                                                        int nb_sectors,
-                                                        int *pnum,
-                                                        BlockDriverState **file);
+int64_t coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs,
+                                                    bool mapping,
+                                                    int64_t offset,
+                                                    int64_t bytes,
+                                                    int64_t *pnum,
+                                                    BlockDriverState **file);
 /*
- * Default implementation for drivers to pass bdrv_co_get_block_status() to
+ * Default implementation for drivers to pass bdrv_co_block_status() to
  * their backing file.
  */
-int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
-                                                           int64_t sector_num,
-                                                           int nb_sectors,
-                                                           int *pnum,
-                                                           BlockDriverState **file);
+int64_t coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs,
+                                                       bool mapping,
+                                                       int64_t offset,
+                                                       int64_t bytes,
+                                                       int64_t *pnum,
+                                                       BlockDriverState **file);
 const char *bdrv_get_parent_name(const BlockDriverState *bs);
 void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp);
 bool blk_dev_has_removable_media(BlockBackend *blk);
diff --git a/block/io.c b/block/io.c
index 4fb544d25c..85c01b2800 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1708,30 +1708,32 @@ typedef struct BdrvCoBlockStatusData {
     bool done;
 } BdrvCoBlockStatusData;

-int64_t coroutine_fn bdrv_co_get_block_status_from_file(BlockDriverState *bs,
-                                                        int64_t sector_num,
-                                                        int nb_sectors,
-                                                        int *pnum,
-                                                        BlockDriverState **file)
+int64_t coroutine_fn bdrv_co_block_status_from_file(BlockDriverState *bs,
+                                                    bool mapping,
+                                                    int64_t offset,
+                                                    int64_t bytes,
+                                                    int64_t *pnum,
+                                                    BlockDriverState **file)
 {
     assert(bs->file && bs->file->bs);
-    *pnum = nb_sectors;
+    *pnum = bytes;
     *file = bs->file->bs;
     return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
-           (sector_num << BDRV_SECTOR_BITS);
+        (offset & BDRV_BLOCK_OFFSET_MASK);
 }

-int64_t coroutine_fn bdrv_co_get_block_status_from_backing(BlockDriverState *bs,
-                                                           int64_t sector_num,
-                                                           int nb_sectors,
-                                                           int *pnum,
-                                                           BlockDriverState **file)
+int64_t coroutine_fn bdrv_co_block_status_from_backing(BlockDriverState *bs,
+                                                       bool mapping,
+                                                       int64_t offset,
+                                                       int64_t bytes,
+                                                       int64_t *pnum,
+                                                       BlockDriverState **file)
 {
     assert(bs->backing && bs->backing->bs);
-    *pnum = nb_sectors;
+    *pnum = bytes;
     *file = bs->backing->bs;
     return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
-           (sector_num << BDRV_SECTOR_BITS);
+        (offset & BDRV_BLOCK_OFFSET_MASK);
 }

 /*
diff --git a/block/blkdebug.c b/block/blkdebug.c
index f54fe33cae..2458912175 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -628,15 +628,16 @@ static int coroutine_fn blkdebug_co_pdiscard(BlockDriverState *bs,
     return bdrv_co_pdiscard(bs->file->bs, offset, bytes);
 }

-static int64_t coroutine_fn blkdebug_co_get_block_status(
-    BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
-    BlockDriverState **file)
+static int64_t coroutine_fn blkdebug_co_block_status(BlockDriverState *bs,
+                                                     bool mapping,
+                                                     int64_t offset,
+                                                     int64_t bytes,
+                                                     int64_t *pnum,
+                                                     BlockDriverState **file)
 {
-    assert(QEMU_IS_ALIGNED(sector_num | nb_sectors,
-                           DIV_ROUND_UP(bs->bl.request_alignment,
-                                        BDRV_SECTOR_SIZE)));
-    return bdrv_co_get_block_status_from_file(bs, sector_num, nb_sectors,
-                                              pnum, file);
+    assert(QEMU_IS_ALIGNED(offset | bytes, bs->bl.request_alignment));
+    return bdrv_co_block_status_from_file(bs, mapping, offset, bytes,
+                                          pnum, file);
 }

 static void blkdebug_close(BlockDriverState *bs)
@@ -908,7 +909,7 @@ static BlockDriver bdrv_blkdebug = {
     .bdrv_co_flush_to_disk  = blkdebug_co_flush,
     .bdrv_co_pwrite_zeroes  = blkdebug_co_pwrite_zeroes,
     .bdrv_co_pdiscard       = blkdebug_co_pdiscard,
-    .bdrv_co_get_block_status = blkdebug_co_get_block_status,
+    .bdrv_co_block_status   = blkdebug_co_block_status,

     .bdrv_debug_event           = blkdebug_debug_event,
     .bdrv_debug_breakpoint      = blkdebug_debug_breakpoint,
diff --git a/block/commit.c b/block/commit.c
index 898d91f653..5516df1a6e 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -269,7 +269,7 @@ static void bdrv_commit_top_child_perm(BlockDriverState *bs, BdrvChild *c,
 static BlockDriver bdrv_commit_top = {
     .format_name                = "commit_top",
     .bdrv_co_preadv             = bdrv_commit_top_preadv,
-    .bdrv_co_get_block_status   = bdrv_co_get_block_status_from_backing,
+    .bdrv_co_block_status       = bdrv_co_block_status_from_backing,
     .bdrv_refresh_filename      = bdrv_commit_top_refresh_filename,
     .bdrv_close                 = bdrv_commit_top_close,
     .bdrv_child_perm            = bdrv_commit_top_child_perm,
diff --git a/block/mirror.c b/block/mirror.c
index fab59739c5..bada3be20a 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -1084,7 +1084,7 @@ static BlockDriver bdrv_mirror_top = {
     .bdrv_co_pwrite_zeroes      = bdrv_mirror_top_pwrite_zeroes,
     .bdrv_co_pdiscard           = bdrv_mirror_top_pdiscard,
     .bdrv_co_flush              = bdrv_mirror_top_flush,
-    .bdrv_co_get_block_status   = bdrv_co_get_block_status_from_backing,
+    .bdrv_co_block_status       = bdrv_co_block_status_from_backing,
     .bdrv_refresh_filename      = bdrv_mirror_top_refresh_filename,
     .bdrv_close                 = bdrv_mirror_top_close,
     .bdrv_child_perm            = bdrv_mirror_top_child_perm,
diff --git a/block/throttle.c b/block/throttle.c
index 5bca76300f..76cd963a8c 100644
--- a/block/throttle.c
+++ b/block/throttle.c
@@ -224,7 +224,7 @@ static BlockDriver bdrv_throttle = {
     .bdrv_reopen_prepare                =   throttle_reopen_prepare,
     .bdrv_reopen_commit                 =   throttle_reopen_commit,
     .bdrv_reopen_abort                  =   throttle_reopen_abort,
-    .bdrv_co_get_block_status           =   bdrv_co_get_block_status_from_file,
+    .bdrv_co_block_status               =   bdrv_co_block_status_from_file,

     .is_filter                          =   true,
 };
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 03/20] file-posix: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 01/20] block: Add .bdrv_co_block_status() callback Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 02/20] block: Switch passthrough drivers to .bdrv_co_block_status() Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-20  9:57   ` Fam Zheng
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 04/20] gluster: " Eric Blake
                   ` (16 subsequent siblings)
  19 siblings, 1 reply; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the file protocol driver accordingly.  In mapping
mode, note that the entire file is reported as allocated, so we can
take a shortcut and skip lseek().

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: tweak comment, add mapping support
---
 block/file-posix.c | 57 ++++++++++++++++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 72ecfbb0e0..6813059867 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2107,24 +2107,25 @@ static int find_allocation(BlockDriverState *bs, off_t start,
 }

 /*
- * Returns the allocation status of the specified sectors.
+ * Returns the allocation status of the specified offset.
  *
- * If 'sector_num' is beyond the end of the disk image the return value is 0
+ * If 'offset' is beyond the end of the disk image the return value is 0
  * and 'pnum' is set to 0.
  *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
+ * 'pnum' is set to the number of bytes (including and immediately following
+ * the specified offset) that are known to be in the same
  * allocated/unallocated state.
  *
- * 'nb_sectors' is the max value 'pnum' should be set to.  If nb_sectors goes
+ * 'bytes' is the max value 'pnum' should be set to.  If bytes goes
  * beyond the end of the disk image it will be clamped.
  */
-static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
-                                                    int64_t sector_num,
-                                                    int nb_sectors, int *pnum,
-                                                    BlockDriverState **file)
+static int64_t coroutine_fn raw_co_block_status(BlockDriverState *bs,
+                                                bool mapping,
+                                                int64_t offset,
+                                                int64_t bytes, int64_t *pnum,
+                                                BlockDriverState **file)
 {
-    off_t start, data = 0, hole = 0;
+    off_t data = 0, hole = 0;
     int64_t total_size;
     int ret;

@@ -2133,39 +2134,45 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
         return ret;
     }

-    start = sector_num * BDRV_SECTOR_SIZE;
     total_size = bdrv_getlength(bs);
     if (total_size < 0) {
         return total_size;
-    } else if (start >= total_size) {
+    } else if (offset >= total_size) {
         *pnum = 0;
         return 0;
-    } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) {
-        nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
+    } else if (offset + bytes > total_size) {
+        bytes = total_size - offset;
     }

-    ret = find_allocation(bs, start, &data, &hole);
+    if (!mapping) {
+        *pnum = bytes;
+        *file = bs;
+        return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
+            (offset & BDRV_BLOCK_OFFSET_MASK);
+    }
+
+    ret = find_allocation(bs, offset, &data, &hole);
     if (ret == -ENXIO) {
         /* Trailing hole */
-        *pnum = nb_sectors;
+        *pnum = bytes;
         ret = BDRV_BLOCK_ZERO;
     } else if (ret < 0) {
         /* No info available, so pretend there are no holes */
-        *pnum = nb_sectors;
+        *pnum = bytes;
         ret = BDRV_BLOCK_DATA;
-    } else if (data == start) {
-        /* On a data extent, compute sectors to the end of the extent,
+    } else if (data == offset) {
+        /* On a data extent, compute bytes to the end of the extent,
          * possibly including a partial sector at EOF. */
-        *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
+        *pnum = MIN(bytes, hole - offset);
         ret = BDRV_BLOCK_DATA;
     } else {
-        /* On a hole, compute sectors to the beginning of the next extent.  */
-        assert(hole == start);
-        *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
+        /* On a hole, compute bytes to the beginning of the next extent.  */
+        assert(hole == offset);
+        *pnum = MIN(bytes, data - offset);
         ret = BDRV_BLOCK_ZERO;
     }
     *file = bs;
-    return ret | BDRV_BLOCK_OFFSET_VALID | start;
+    return ret | BDRV_BLOCK_OFFSET_VALID | (offset & BDRV_BLOCK_OFFSET_MASK);
 }

 static coroutine_fn BlockAIOCB *raw_aio_pdiscard(BlockDriverState *bs,
@@ -2259,7 +2266,7 @@ BlockDriver bdrv_file = {
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
-    .bdrv_co_get_block_status = raw_co_get_block_status,
+    .bdrv_co_block_status = raw_co_block_status,
     .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,

     .bdrv_co_preadv         = raw_co_preadv,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 04/20] gluster: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (2 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 03/20] file-posix: Switch " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 05/20] iscsi: Switch cluster_sectors to byte-based Eric Blake
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Jeff Cody, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the gluster driver accordingly.  In mapping
mode, note that the entire file is reported as allocated, so we can
take a shortcut and skip find_allocation().

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: tweak comments [Prasanna], add mapping, drop R-b
---
 block/gluster.c | 62 +++++++++++++++++++++++++++++++--------------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 0f4265a3a4..f128db3e1f 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -1349,26 +1349,26 @@ exit:
 }

 /*
- * Returns the allocation status of the specified sectors.
+ * Returns the allocation status of the specified offset.
  *
- * If 'sector_num' is beyond the end of the disk image the return value is 0
+ * If 'offset' is beyond the end of the disk image the return value is 0
  * and 'pnum' is set to 0.
  *
- * 'pnum' is set to the number of sectors (including and immediately following
- * the specified sector) that are known to be in the same
+ * 'pnum' is set to the number of bytes (including and immediately following
+ * the specified offset) that are known to be in the same
  * allocated/unallocated state.
  *
- * 'nb_sectors' is the max value 'pnum' should be set to.  If nb_sectors goes
+ * 'bytes' is the max value 'pnum' should be set to.  If bytes goes
  * beyond the end of the disk image it will be clamped.
  *
- * (Based on raw_co_get_block_status() from file-posix.c.)
+ * (Based on raw_co_block_status() from file-posix.c.)
  */
-static int64_t coroutine_fn qemu_gluster_co_get_block_status(
-        BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum,
-        BlockDriverState **file)
+static int64_t coroutine_fn qemu_gluster_co_block_status(
+        BlockDriverState *bs, bool mapping, int64_t offset, int64_t bytes,
+        int64_t *pnum, BlockDriverState **file)
 {
     BDRVGlusterState *s = bs->opaque;
-    off_t start, data = 0, hole = 0;
+    off_t data = 0, hole = 0;
     int64_t total_size;
     int ret = -EINVAL;

@@ -1376,41 +1376,47 @@ static int64_t coroutine_fn qemu_gluster_co_get_block_status(
         return ret;
     }

-    start = sector_num * BDRV_SECTOR_SIZE;
     total_size = bdrv_getlength(bs);
     if (total_size < 0) {
         return total_size;
-    } else if (start >= total_size) {
+    } else if (offset >= total_size) {
         *pnum = 0;
         return 0;
-    } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) {
-        nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
+    } else if (offset + bytes > total_size) {
+        bytes = total_size - offset;
     }

-    ret = find_allocation(bs, start, &data, &hole);
+    if (!mapping) {
+        *pnum = bytes;
+        *file = bs;
+        return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
+            (offset & BDRV_BLOCK_OFFSET_MASK);
+    }
+
+    ret = find_allocation(bs, offset, &data, &hole);
     if (ret == -ENXIO) {
         /* Trailing hole */
-        *pnum = nb_sectors;
+        *pnum = bytes;
         ret = BDRV_BLOCK_ZERO;
     } else if (ret < 0) {
         /* No info available, so pretend there are no holes */
-        *pnum = nb_sectors;
+        *pnum = bytes;
         ret = BDRV_BLOCK_DATA;
-    } else if (data == start) {
-        /* On a data extent, compute sectors to the end of the extent,
+    } else if (data == offset) {
+        /* On a data extent, compute bytes to the end of the extent,
          * possibly including a partial sector at EOF. */
-        *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
+        *pnum = MIN(bytes, hole - offset);
         ret = BDRV_BLOCK_DATA;
     } else {
-        /* On a hole, compute sectors to the beginning of the next extent.  */
-        assert(hole == start);
-        *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
+        /* On a hole, compute bytes to the beginning of the next extent.  */
+        assert(hole == offset);
+        *pnum = MIN(bytes, data - offset);
         ret = BDRV_BLOCK_ZERO;
     }

     *file = bs;

-    return ret | BDRV_BLOCK_OFFSET_VALID | start;
+    return ret | BDRV_BLOCK_OFFSET_VALID | (offset & BDRV_BLOCK_OFFSET_MASK);
 }


@@ -1438,7 +1444,7 @@ static BlockDriver bdrv_gluster = {
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
     .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
+    .bdrv_co_block_status         = qemu_gluster_co_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };

@@ -1466,7 +1472,7 @@ static BlockDriver bdrv_gluster_tcp = {
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
     .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
+    .bdrv_co_block_status         = qemu_gluster_co_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };

@@ -1494,7 +1500,7 @@ static BlockDriver bdrv_gluster_unix = {
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
     .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
+    .bdrv_co_block_status         = qemu_gluster_co_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };

@@ -1528,7 +1534,7 @@ static BlockDriver bdrv_gluster_rdma = {
 #ifdef CONFIG_GLUSTERFS_ZEROFILL
     .bdrv_co_pwrite_zeroes        = qemu_gluster_co_pwrite_zeroes,
 #endif
-    .bdrv_co_get_block_status     = qemu_gluster_co_get_block_status,
+    .bdrv_co_block_status         = qemu_gluster_co_block_status,
     .create_opts                  = &qemu_gluster_create_opts,
 };

-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 05/20] iscsi: Switch cluster_sectors to byte-based
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (3 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 04/20] gluster: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 06/20] iscsi: Switch iscsi_allocmap_update() " Eric Blake
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, jsnow, famz, qemu-block, Ronnie Sahlberg, Paolo Bonzini,
	Peter Lieven, Max Reitz

We are gradually converting to byte-based interfaces, as they are
easier to reason about than sector-based.  Convert all uses of
the cluster size in sectors, along with adding assertions that we
are not dividing by zero.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: no change
---
 block/iscsi.c | 56 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 21 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 8b47d30dcc..08f43ddb0c 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -79,7 +79,7 @@ typedef struct IscsiLun {
     unsigned long *allocmap;
     unsigned long *allocmap_valid;
     long allocmap_size;
-    int cluster_sectors;
+    int cluster_size;
     bool use_16_for_rw;
     bool write_protected;
     bool lbpme;
@@ -460,9 +460,10 @@ static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
 {
     iscsi_allocmap_free(iscsilun);

+    assert(iscsilun->cluster_size);
     iscsilun->allocmap_size =
-        DIV_ROUND_UP(sector_lun2qemu(iscsilun->num_blocks, iscsilun),
-                     iscsilun->cluster_sectors);
+        DIV_ROUND_UP(iscsilun->num_blocks * iscsilun->block_size,
+                     iscsilun->cluster_size);

     iscsilun->allocmap = bitmap_try_new(iscsilun->allocmap_size);
     if (!iscsilun->allocmap) {
@@ -470,7 +471,7 @@ static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
     }

     if (open_flags & BDRV_O_NOCACHE) {
-        /* in case that cache.direct = on all allocmap entries are
+        /* when cache.direct = on all allocmap entries are
          * treated as invalid to force a relookup of the block
          * status on every read request */
         return 0;
@@ -491,17 +492,19 @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
                       int nb_sectors, bool allocated, bool valid)
 {
     int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;
+    int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;

     if (iscsilun->allocmap == NULL) {
         return;
     }
     /* expand to entirely contain all affected clusters */
-    cl_num_expanded = sector_num / iscsilun->cluster_sectors;
+    assert(cluster_sectors);
+    cl_num_expanded = sector_num / cluster_sectors;
     nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,
-                                   iscsilun->cluster_sectors) - cl_num_expanded;
+                                   cluster_sectors) - cl_num_expanded;
     /* shrink to touch only completely contained clusters */
-    cl_num_shrunk = DIV_ROUND_UP(sector_num, iscsilun->cluster_sectors);
-    nb_cls_shrunk = (sector_num + nb_sectors) / iscsilun->cluster_sectors
+    cl_num_shrunk = DIV_ROUND_UP(sector_num, cluster_sectors);
+    nb_cls_shrunk = (sector_num + nb_sectors) / cluster_sectors
                       - cl_num_shrunk;
     if (allocated) {
         bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
@@ -565,9 +568,12 @@ iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num,
     if (iscsilun->allocmap == NULL) {
         return true;
     }
-    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
+    assert(iscsilun->cluster_size);
+    size = DIV_ROUND_UP(sector_num + nb_sectors,
+                        iscsilun->cluster_size >> BDRV_SECTOR_BITS);
     return !(find_next_bit(iscsilun->allocmap, size,
-                           sector_num / iscsilun->cluster_sectors) == size);
+                           sector_num * BDRV_SECTOR_SIZE /
+                           iscsilun->cluster_size) == size);
 }

 static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
@@ -577,9 +583,12 @@ static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
     if (iscsilun->allocmap_valid == NULL) {
         return false;
     }
-    size = DIV_ROUND_UP(sector_num + nb_sectors, iscsilun->cluster_sectors);
+    assert(iscsilun->cluster_size);
+    size = DIV_ROUND_UP(sector_num + nb_sectors,
+                        iscsilun->cluster_size >> BDRV_SECTOR_BITS);
     return (find_next_zero_bit(iscsilun->allocmap_valid, size,
-                               sector_num / iscsilun->cluster_sectors) == size);
+                               sector_num * BDRV_SECTOR_SIZE /
+                               iscsilun->cluster_size) == size);
 }

 static int coroutine_fn
@@ -814,16 +823,21 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
         BlockDriverState *file;
         /* check the block status from the beginning of the cluster
          * containing the start sector */
-        int64_t ret = iscsi_co_get_block_status(bs,
-                          sector_num - sector_num % iscsilun->cluster_sectors,
-                          BDRV_REQUEST_MAX_SECTORS, &pnum, &file);
+        int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;
+        int head;
+        int64_t ret;
+
+        assert(cluster_sectors);
+        head = sector_num % cluster_sectors;
+        ret = iscsi_co_get_block_status(bs, sector_num - head,
+                                        BDRV_REQUEST_MAX_SECTORS, &pnum,
+                                        &file);
         if (ret < 0) {
             return ret;
         }
         /* if the whole request falls into an unallocated area we can avoid
-         * to read and directly return zeroes instead */
-        if (ret & BDRV_BLOCK_ZERO &&
-            pnum >= nb_sectors + sector_num % iscsilun->cluster_sectors) {
+         * reading and directly return zeroes instead */
+        if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors + head) {
             qemu_iovec_memset(iov, 0, 0x00, iov->size);
             return 0;
         }
@@ -1963,8 +1977,8 @@ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags,
      * reasonable size */
     if (iscsilun->bl.opt_unmap_gran * iscsilun->block_size >= 4 * 1024 &&
         iscsilun->bl.opt_unmap_gran * iscsilun->block_size <= 16 * 1024 * 1024) {
-        iscsilun->cluster_sectors = (iscsilun->bl.opt_unmap_gran *
-                                     iscsilun->block_size) >> BDRV_SECTOR_BITS;
+        iscsilun->cluster_size = iscsilun->bl.opt_unmap_gran *
+            iscsilun->block_size;
         if (iscsilun->lbprz) {
             ret = iscsi_allocmap_init(iscsilun, bs->open_flags);
         }
@@ -2170,7 +2184,7 @@ static int iscsi_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     IscsiLun *iscsilun = bs->opaque;
     bdi->unallocated_blocks_are_zero = iscsilun->lbprz;
     bdi->can_write_zeroes_with_unmap = iscsilun->lbprz && iscsilun->lbp.lbpws;
-    bdi->cluster_size = iscsilun->cluster_sectors * BDRV_SECTOR_SIZE;
+    bdi->cluster_size = iscsilun->cluster_size;
     return 0;
 }

-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 06/20] iscsi: Switch iscsi_allocmap_update() to byte-based
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (4 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 05/20] iscsi: Switch cluster_sectors to byte-based Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 07/20] iscsi: Switch to .bdrv_co_block_status() Eric Blake
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, jsnow, famz, qemu-block, Ronnie Sahlberg, Paolo Bonzini,
	Peter Lieven, Max Reitz

We are gradually converting to byte-based interfaces, as they are
easier to reason about than sector-based.  Convert all uses of
the allocmap (no semantic change).  Callers that already had bytes
available are simpler, and callers that now scale to bytes will be
easier to switch to byte-based in the future.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to count/bytes rename
---
 block/iscsi.c | 90 +++++++++++++++++++++++++++++------------------------------
 1 file changed, 44 insertions(+), 46 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 08f43ddb0c..5af145194d 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -488,24 +488,22 @@ static int iscsi_allocmap_init(IscsiLun *iscsilun, int open_flags)
 }

 static void
-iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
-                      int nb_sectors, bool allocated, bool valid)
+iscsi_allocmap_update(IscsiLun *iscsilun, int64_t offset,
+                      int64_t bytes, bool allocated, bool valid)
 {
     int64_t cl_num_expanded, nb_cls_expanded, cl_num_shrunk, nb_cls_shrunk;
-    int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;

     if (iscsilun->allocmap == NULL) {
         return;
     }
     /* expand to entirely contain all affected clusters */
-    assert(cluster_sectors);
-    cl_num_expanded = sector_num / cluster_sectors;
-    nb_cls_expanded = DIV_ROUND_UP(sector_num + nb_sectors,
-                                   cluster_sectors) - cl_num_expanded;
+    assert(iscsilun->cluster_size);
+    cl_num_expanded = offset / iscsilun->cluster_size;
+    nb_cls_expanded = DIV_ROUND_UP(offset + bytes, iscsilun->cluster_size)
+        - cl_num_expanded;
     /* shrink to touch only completely contained clusters */
-    cl_num_shrunk = DIV_ROUND_UP(sector_num, cluster_sectors);
-    nb_cls_shrunk = (sector_num + nb_sectors) / cluster_sectors
-                      - cl_num_shrunk;
+    cl_num_shrunk = DIV_ROUND_UP(offset, iscsilun->cluster_size);
+    nb_cls_shrunk = (offset + bytes) / iscsilun->cluster_size - cl_num_shrunk;
     if (allocated) {
         bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
     } else {
@@ -528,26 +526,26 @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t sector_num,
 }

 static void
-iscsi_allocmap_set_allocated(IscsiLun *iscsilun, int64_t sector_num,
-                             int nb_sectors)
+iscsi_allocmap_set_allocated(IscsiLun *iscsilun, int64_t offset,
+                             int64_t bytes)
 {
-    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, true, true);
+    iscsi_allocmap_update(iscsilun, offset, bytes, true, true);
 }

 static void
-iscsi_allocmap_set_unallocated(IscsiLun *iscsilun, int64_t sector_num,
-                               int nb_sectors)
+iscsi_allocmap_set_unallocated(IscsiLun *iscsilun, int64_t offset,
+                               int64_t bytes)
 {
     /* Note: if cache.direct=on the fifth argument to iscsi_allocmap_update
      * is ignored, so this will in effect be an iscsi_allocmap_set_invalid.
      */
-    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, true);
+    iscsi_allocmap_update(iscsilun, offset, bytes, false, true);
 }

-static void iscsi_allocmap_set_invalid(IscsiLun *iscsilun, int64_t sector_num,
-                                       int nb_sectors)
+static void iscsi_allocmap_set_invalid(IscsiLun *iscsilun, int64_t offset,
+                                       int64_t bytes)
 {
-    iscsi_allocmap_update(iscsilun, sector_num, nb_sectors, false, false);
+    iscsi_allocmap_update(iscsilun, offset, bytes, false, false);
 }

 static void iscsi_allocmap_invalidate(IscsiLun *iscsilun)
@@ -561,34 +559,30 @@ static void iscsi_allocmap_invalidate(IscsiLun *iscsilun)
 }

 static inline bool
-iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t sector_num,
-                            int nb_sectors)
+iscsi_allocmap_is_allocated(IscsiLun *iscsilun, int64_t offset,
+                            int64_t bytes)
 {
     unsigned long size;
     if (iscsilun->allocmap == NULL) {
         return true;
     }
     assert(iscsilun->cluster_size);
-    size = DIV_ROUND_UP(sector_num + nb_sectors,
-                        iscsilun->cluster_size >> BDRV_SECTOR_BITS);
+    size = DIV_ROUND_UP(offset + bytes, iscsilun->cluster_size);
     return !(find_next_bit(iscsilun->allocmap, size,
-                           sector_num * BDRV_SECTOR_SIZE /
-                           iscsilun->cluster_size) == size);
+                           offset / iscsilun->cluster_size) == size);
 }

 static inline bool iscsi_allocmap_is_valid(IscsiLun *iscsilun,
-                                           int64_t sector_num, int nb_sectors)
+                                           int64_t offset, int64_t bytes)
 {
     unsigned long size;
     if (iscsilun->allocmap_valid == NULL) {
         return false;
     }
     assert(iscsilun->cluster_size);
-    size = DIV_ROUND_UP(sector_num + nb_sectors,
-                        iscsilun->cluster_size >> BDRV_SECTOR_BITS);
+    size = DIV_ROUND_UP(offset + bytes, iscsilun->cluster_size);
     return (find_next_zero_bit(iscsilun->allocmap_valid, size,
-                               sector_num * BDRV_SECTOR_SIZE /
-                               iscsilun->cluster_size) == size);
+                               offset / iscsilun->cluster_size) == size);
 }

 static int coroutine_fn
@@ -670,12 +664,14 @@ retry:
     }

     if (iTask.status != SCSI_STATUS_GOOD) {
-        iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors);
+        iscsi_allocmap_set_invalid(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                   nb_sectors * BDRV_SECTOR_SIZE);
         r = iTask.err_code;
         goto out_unlock;
     }

-    iscsi_allocmap_set_allocated(iscsilun, sector_num, nb_sectors);
+    iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                 nb_sectors * BDRV_SECTOR_SIZE);

 out_unlock:
     qemu_mutex_unlock(&iscsilun->mutex);
@@ -770,9 +766,11 @@ retry:
     }

     if (ret & BDRV_BLOCK_ZERO) {
-        iscsi_allocmap_set_unallocated(iscsilun, sector_num, *pnum);
+        iscsi_allocmap_set_unallocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                       *pnum * BDRV_SECTOR_SIZE);
     } else {
-        iscsi_allocmap_set_allocated(iscsilun, sector_num, *pnum);
+        iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                     *pnum * BDRV_SECTOR_SIZE);
     }

     if (*pnum > nb_sectors) {
@@ -810,15 +808,19 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
     /* if cache.direct is off and we have a valid entry in our allocation map
      * we can skip checking the block status and directly return zeroes if
      * the request falls within an unallocated area */
-    if (iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
-        !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
+    if (iscsi_allocmap_is_valid(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                nb_sectors * BDRV_SECTOR_SIZE) &&
+        !iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                     nb_sectors * BDRV_SECTOR_SIZE)) {
             qemu_iovec_memset(iov, 0, 0x00, iov->size);
             return 0;
     }

     if (nb_sectors >= ISCSI_CHECKALLOC_THRES &&
-        !iscsi_allocmap_is_valid(iscsilun, sector_num, nb_sectors) &&
-        !iscsi_allocmap_is_allocated(iscsilun, sector_num, nb_sectors)) {
+        !iscsi_allocmap_is_valid(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                 nb_sectors * BDRV_SECTOR_SIZE) &&
+        !iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
+                                     nb_sectors * BDRV_SECTOR_SIZE)) {
         int pnum;
         BlockDriverState *file;
         /* check the block status from the beginning of the cluster
@@ -1187,8 +1189,7 @@ retry:
         goto out_unlock;
     }

-    iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
-                               bytes >> BDRV_SECTOR_BITS);
+    iscsi_allocmap_set_invalid(iscsilun, offset, bytes);

 out_unlock:
     qemu_mutex_unlock(&iscsilun->mutex);
@@ -1286,18 +1287,15 @@ retry:
     }

     if (iTask.status != SCSI_STATUS_GOOD) {
-        iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                   bytes >> BDRV_SECTOR_BITS);
+        iscsi_allocmap_set_invalid(iscsilun, offset, bytes);
         r = iTask.err_code;
         goto out_unlock;
     }

     if (flags & BDRV_REQ_MAY_UNMAP) {
-        iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                   bytes >> BDRV_SECTOR_BITS);
+        iscsi_allocmap_set_invalid(iscsilun, offset, bytes);
     } else {
-        iscsi_allocmap_set_allocated(iscsilun, offset >> BDRV_SECTOR_BITS,
-                                     bytes >> BDRV_SECTOR_BITS);
+        iscsi_allocmap_set_allocated(iscsilun, offset, bytes);
     }

 out_unlock:
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 07/20] iscsi: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (5 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 06/20] iscsi: Switch iscsi_allocmap_update() " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 08/20] null: " Eric Blake
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, jsnow, famz, qemu-block, Ronnie Sahlberg, Paolo Bonzini,
	Peter Lieven, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the iscsi driver accordingly.  In this case,
it is handy to teach iscsi_co_block_status() to handle a NULL file
parameter, even though the block layer passes a non-NULL value,
because we also call the function directly.  For now, there are
no optimizations done based on the mapping flag.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping parameter
---
 block/iscsi.c | 54 ++++++++++++++++++++++++++----------------------------
 1 file changed, 26 insertions(+), 28 deletions(-)

diff --git a/block/iscsi.c b/block/iscsi.c
index 5af145194d..ab125a6340 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -680,9 +680,10 @@ out_unlock:



-static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
-                                                  int64_t sector_num,
-                                                  int nb_sectors, int *pnum,
+static int64_t coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
+                                                  bool mapping,
+                                                  int64_t offset,
+                                                  int64_t bytes, int64_t *pnum,
                                                   BlockDriverState **file)
 {
     IscsiLun *iscsilun = bs->opaque;
@@ -693,15 +694,15 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,

     iscsi_co_init_iscsitask(iscsilun, &iTask);

-    if (!is_sector_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {
+    if (!is_byte_request_lun_aligned(offset, bytes, iscsilun)) {
         ret = -EINVAL;
         goto out;
     }

     /* default to all sectors allocated */
     ret = BDRV_BLOCK_DATA;
-    ret |= (sector_num << BDRV_SECTOR_BITS) | BDRV_BLOCK_OFFSET_VALID;
-    *pnum = nb_sectors;
+    ret |= (offset & BDRV_BLOCK_OFFSET_MASK) | BDRV_BLOCK_OFFSET_VALID;
+    *pnum = bytes;

     /* LUN does not support logical block provisioning */
     if (!iscsilun->lbpme) {
@@ -711,7 +712,7 @@ static int64_t coroutine_fn iscsi_co_get_block_status(BlockDriverState *bs,
     qemu_mutex_lock(&iscsilun->mutex);
 retry:
     if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun,
-                                  sector_qemu2lun(sector_num, iscsilun),
+                                  offset / iscsilun->block_size,
                                   8 + 16, iscsi_co_generic_cb,
                                   &iTask) == NULL) {
         ret = -ENOMEM;
@@ -750,12 +751,12 @@ retry:

     lbasd = &lbas->descriptors[0];

-    if (sector_qemu2lun(sector_num, iscsilun) != lbasd->lba) {
+    if (offset / iscsilun->block_size != lbasd->lba) {
         ret = -EIO;
         goto out_unlock;
     }

-    *pnum = sector_lun2qemu(lbasd->num_blocks, iscsilun);
+    *pnum = lbasd->num_blocks * iscsilun->block_size;

     if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
         lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
@@ -766,15 +767,13 @@ retry:
     }

     if (ret & BDRV_BLOCK_ZERO) {
-        iscsi_allocmap_set_unallocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
-                                       *pnum * BDRV_SECTOR_SIZE);
+        iscsi_allocmap_set_unallocated(iscsilun, offset, *pnum);
     } else {
-        iscsi_allocmap_set_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
-                                     *pnum * BDRV_SECTOR_SIZE);
+        iscsi_allocmap_set_allocated(iscsilun, offset, *pnum);
     }

-    if (*pnum > nb_sectors) {
-        *pnum = nb_sectors;
+    if (*pnum > bytes) {
+        *pnum = bytes;
     }
 out_unlock:
     qemu_mutex_unlock(&iscsilun->mutex);
@@ -782,7 +781,7 @@ out:
     if (iTask.task != NULL) {
         scsi_free_scsi_task(iTask.task);
     }
-    if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
+    if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID && file) {
         *file = bs;
     }
     return ret;
@@ -821,25 +820,24 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState *bs,
                                  nb_sectors * BDRV_SECTOR_SIZE) &&
         !iscsi_allocmap_is_allocated(iscsilun, sector_num * BDRV_SECTOR_SIZE,
                                      nb_sectors * BDRV_SECTOR_SIZE)) {
-        int pnum;
-        BlockDriverState *file;
+        int64_t pnum;
         /* check the block status from the beginning of the cluster
          * containing the start sector */
-        int cluster_sectors = iscsilun->cluster_size >> BDRV_SECTOR_BITS;
-        int head;
+        int64_t head;
         int64_t ret;

-        assert(cluster_sectors);
-        head = sector_num % cluster_sectors;
-        ret = iscsi_co_get_block_status(bs, sector_num - head,
-                                        BDRV_REQUEST_MAX_SECTORS, &pnum,
-                                        &file);
+        assert(iscsilun->cluster_size);
+        head = (sector_num * BDRV_SECTOR_SIZE) % iscsilun->cluster_size;
+        ret = iscsi_co_block_status(bs, false,
+                                    sector_num * BDRV_SECTOR_SIZE - head,
+                                    BDRV_REQUEST_MAX_BYTES, &pnum, NULL);
         if (ret < 0) {
             return ret;
         }
         /* if the whole request falls into an unallocated area we can avoid
          * reading and directly return zeroes instead */
-        if (ret & BDRV_BLOCK_ZERO && pnum >= nb_sectors + head) {
+        if (ret & BDRV_BLOCK_ZERO &&
+            pnum >= nb_sectors * BDRV_SECTOR_SIZE + head) {
             qemu_iovec_memset(iov, 0, 0x00, iov->size);
             return 0;
         }
@@ -2225,7 +2223,7 @@ static BlockDriver bdrv_iscsi = {
     .bdrv_truncate   = iscsi_truncate,
     .bdrv_refresh_limits = iscsi_refresh_limits,

-    .bdrv_co_get_block_status = iscsi_co_get_block_status,
+    .bdrv_co_block_status  = iscsi_co_block_status,
     .bdrv_co_pdiscard      = iscsi_co_pdiscard,
     .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
     .bdrv_co_readv         = iscsi_co_readv,
@@ -2260,7 +2258,7 @@ static BlockDriver bdrv_iser = {
     .bdrv_truncate   = iscsi_truncate,
     .bdrv_refresh_limits = iscsi_refresh_limits,

-    .bdrv_co_get_block_status = iscsi_co_get_block_status,
+    .bdrv_co_block_status  = iscsi_co_block_status,
     .bdrv_co_pdiscard      = iscsi_co_pdiscard,
     .bdrv_co_pwrite_zeroes = iscsi_co_pwrite_zeroes,
     .bdrv_co_readv         = iscsi_co_readv,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 08/20] null: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (6 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 07/20] iscsi: Switch to .bdrv_co_block_status() Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 09/20] parallels: " Eric Blake
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the null driver accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping parameter
---
 block/null.c | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/block/null.c b/block/null.c
index dd9c13f9ba..d34c482066 100644
--- a/block/null.c
+++ b/block/null.c
@@ -223,22 +223,22 @@ static int null_reopen_prepare(BDRVReopenState *reopen_state,
     return 0;
 }

-static int64_t coroutine_fn null_co_get_block_status(BlockDriverState *bs,
-                                                     int64_t sector_num,
-                                                     int nb_sectors, int *pnum,
-                                                     BlockDriverState **file)
+static int64_t coroutine_fn null_co_block_status(BlockDriverState *bs,
+                                                 bool mapping,
+                                                 int64_t offset,
+                                                 int64_t bytes, int64_t *pnum,
+                                                 BlockDriverState **file)
 {
     BDRVNullState *s = bs->opaque;
-    off_t start = sector_num * BDRV_SECTOR_SIZE;
+    int64_t ret = BDRV_BLOCK_OFFSET_VALID | (offset & BDRV_BLOCK_OFFSET_MASK);

-    *pnum = nb_sectors;
+    *pnum = bytes;
     *file = bs;

     if (s->read_zeroes) {
-        return BDRV_BLOCK_OFFSET_VALID | start | BDRV_BLOCK_ZERO;
-    } else {
-        return BDRV_BLOCK_OFFSET_VALID | start;
+        ret |= BDRV_BLOCK_ZERO;
     }
+    return ret;
 }

 static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
@@ -270,7 +270,7 @@ static BlockDriver bdrv_null_co = {
     .bdrv_co_flush_to_disk  = null_co_flush,
     .bdrv_reopen_prepare    = null_reopen_prepare,

-    .bdrv_co_get_block_status   = null_co_get_block_status,
+    .bdrv_co_block_status   = null_co_block_status,

     .bdrv_refresh_filename  = null_refresh_filename,
 };
@@ -290,7 +290,7 @@ static BlockDriver bdrv_null_aio = {
     .bdrv_aio_flush         = null_aio_flush,
     .bdrv_reopen_prepare    = null_reopen_prepare,

-    .bdrv_co_get_block_status   = null_co_get_block_status,
+    .bdrv_co_block_status   = null_co_block_status,

     .bdrv_refresh_filename  = null_refresh_filename,
 };
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 09/20] parallels: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (7 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 08/20] null: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 10/20] qcow: " Eric Blake
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, jsnow, famz, qemu-block, Stefan Hajnoczi, Denis V. Lunev,
	Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the parallels driver accordingly.  Note that
the internal function block_status() is still sector-based, because
it is still in use by other sector-based functions; but that's okay
because request_alignment is 512 as a result of those functions.
For now, no optimizations are added based on the mapping hint.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>

---
v2: rebase to mapping parameter; it is ignored, so R-b kept
---
 block/parallels.c | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/block/parallels.c b/block/parallels.c
index 2b6c6e5709..37dddfd2e9 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -278,22 +278,29 @@ static coroutine_fn int parallels_co_flush_to_os(BlockDriverState *bs)
 }


-static int64_t coroutine_fn parallels_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int64_t coroutine_fn parallels_co_block_status(BlockDriverState *bs,
+                                                      bool mapping,
+                                                      int64_t offset,
+                                                      int64_t bytes,
+                                                      int64_t *pnum,
+                                                      BlockDriverState **file)
 {
     BDRVParallelsState *s = bs->opaque;
-    int64_t offset;
+    int count;

+    assert(QEMU_IS_ALIGNED(offset | bytes, BDRV_SECTOR_SIZE));
     qemu_co_mutex_lock(&s->lock);
-    offset = block_status(s, sector_num, nb_sectors, pnum);
+    offset = block_status(s, offset >> BDRV_SECTOR_BITS,
+                          bytes >> BDRV_SECTOR_BITS, &count);
     qemu_co_mutex_unlock(&s->lock);

     if (offset < 0) {
         return 0;
     }

+    *pnum = count * BDRV_SECTOR_SIZE;
     *file = bs->file->bs;
-    return (offset << BDRV_SECTOR_BITS) |
+    return (offset & BDRV_BLOCK_OFFSET_MASK) |
         BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID;
 }

@@ -781,7 +788,7 @@ static BlockDriver bdrv_parallels = {
     .bdrv_open		= parallels_open,
     .bdrv_close		= parallels_close,
     .bdrv_child_perm          = bdrv_format_default_perms,
-    .bdrv_co_get_block_status = parallels_co_get_block_status,
+    .bdrv_co_block_status     = parallels_co_block_status,
     .bdrv_has_zero_init       = bdrv_has_zero_init_1,
     .bdrv_co_flush_to_os      = parallels_co_flush_to_os,
     .bdrv_co_readv  = parallels_co_readv,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 10/20] qcow: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (8 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 09/20] parallels: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 11/20] qcow2: " Eric Blake
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the qcow driver accordingly.  There is no
intent to optimize based on the mapping flag for this format.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v3: rebase to master
v2: rebase to mapping flag
---
 block/qcow.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/block/qcow.c b/block/qcow.c
index f450b00cfc..ee521d590c 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -511,23 +511,28 @@ static int get_cluster_offset(BlockDriverState *bs,
     return 1;
 }

-static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int64_t coroutine_fn qcow_co_block_status(BlockDriverState *bs,
+                                                 bool mapping,
+                                                 int64_t offset, int64_t bytes,
+                                                 int64_t *pnum,
+                                                 BlockDriverState **file)
 {
     BDRVQcowState *s = bs->opaque;
-    int index_in_cluster, n, ret;
+    int index_in_cluster, ret;
+    int64_t n;
     uint64_t cluster_offset;

     qemu_co_mutex_lock(&s->lock);
-    ret = get_cluster_offset(bs, sector_num << 9, 0, 0, 0, 0, &cluster_offset);
+    ret = get_cluster_offset(bs, offset, 0, 0, 0, 0, &cluster_offset);
     qemu_co_mutex_unlock(&s->lock);
     if (ret < 0) {
         return ret;
     }
-    index_in_cluster = sector_num & (s->cluster_sectors - 1);
-    n = s->cluster_sectors - index_in_cluster;
-    if (n > nb_sectors)
-        n = nb_sectors;
+    index_in_cluster = offset & (s->cluster_size - 1);
+    n = s->cluster_size - index_in_cluster;
+    if (n > bytes) {
+        n = bytes;
+    }
     *pnum = n;
     if (!cluster_offset) {
         return 0;
@@ -535,7 +540,7 @@ static int64_t coroutine_fn qcow_co_get_block_status(BlockDriverState *bs,
     if ((cluster_offset & QCOW_OFLAG_COMPRESSED) || s->crypto) {
         return BDRV_BLOCK_DATA;
     }
-    cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
+    cluster_offset |= (index_in_cluster & BDRV_BLOCK_OFFSET_MASK);
     *file = bs->file->bs;
     return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | cluster_offset;
 }
@@ -1108,7 +1113,7 @@ static BlockDriver bdrv_qcow = {

     .bdrv_co_readv          = qcow_co_readv,
     .bdrv_co_writev         = qcow_co_writev,
-    .bdrv_co_get_block_status   = qcow_co_get_block_status,
+    .bdrv_co_block_status   = qcow_co_block_status,

     .bdrv_make_empty        = qcow_make_empty,
     .bdrv_co_pwritev_compressed = qcow_co_pwritev_compressed,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 11/20] qcow2: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (9 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 10/20] qcow: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 12/20] qed: " Eric Blake
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the qcow2 driver accordingly.

For now, we are ignoring the 'mapping' hint.  However, it should
be relatively straightforward to honor the hint as a way to return
larger *pnum values when we have consecutive clusters with the same
data/zero status but which differ only in having non-consecutive
mappings.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping flag
---
 block/qcow2.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 721cb077fe..de5f737681 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1624,8 +1624,12 @@ static void qcow2_join_options(QDict *options, QDict *old_options)
     }
 }

-static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int64_t coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
+                                                  bool mapping,
+                                                  int64_t offset,
+                                                  int64_t count,
+                                                  int64_t *pnum,
+                                                  BlockDriverState **file)
 {
     BDRVQcow2State *s = bs->opaque;
     uint64_t cluster_offset;
@@ -1633,21 +1637,20 @@ static int64_t coroutine_fn qcow2_co_get_block_status(BlockDriverState *bs,
     unsigned int bytes;
     int64_t status = 0;

-    bytes = MIN(INT_MAX, nb_sectors * BDRV_SECTOR_SIZE);
+    bytes = MIN(INT_MAX, count);
     qemu_co_mutex_lock(&s->lock);
-    ret = qcow2_get_cluster_offset(bs, sector_num << 9, &bytes,
-                                   &cluster_offset);
+    ret = qcow2_get_cluster_offset(bs, offset, &bytes, &cluster_offset);
     qemu_co_mutex_unlock(&s->lock);
     if (ret < 0) {
         return ret;
     }

-    *pnum = bytes >> BDRV_SECTOR_BITS;
+    *pnum = bytes;

     if (cluster_offset != 0 && ret != QCOW2_CLUSTER_COMPRESSED &&
         !s->crypto) {
-        index_in_cluster = sector_num & (s->cluster_sectors - 1);
-        cluster_offset |= (index_in_cluster << BDRV_SECTOR_BITS);
+        index_in_cluster = offset & (s->cluster_size - 1);
+        cluster_offset |= (index_in_cluster & BDRV_BLOCK_OFFSET_MASK);
         *file = bs->file->bs;
         status |= BDRV_BLOCK_OFFSET_VALID | cluster_offset;
     }
@@ -4259,7 +4262,7 @@ BlockDriver bdrv_qcow2 = {
     .bdrv_child_perm      = bdrv_format_default_perms,
     .bdrv_create        = qcow2_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
-    .bdrv_co_get_block_status = qcow2_co_get_block_status,
+    .bdrv_co_block_status = qcow2_co_block_status,

     .bdrv_co_preadv         = qcow2_co_preadv,
     .bdrv_co_pwritev        = qcow2_co_pwritev,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 12/20] qed: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (10 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 11/20] qcow2: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 13/20] raw: " Eric Blake
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Stefan Hajnoczi, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the qed driver accordingly.  There is no intent
to optimize based on the mapping flag for this format.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping flag, fix mask in qed_is_allocated_cb
---
 block/qed.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/block/qed.c b/block/qed.c
index 28e2ec89e8..16752e50c0 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -693,7 +693,7 @@ typedef struct {
     Coroutine *co;
     uint64_t pos;
     int64_t status;
-    int *pnum;
+    int64_t *pnum;
     BlockDriverState **file;
 } QEDIsAllocatedCB;

@@ -702,10 +702,10 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l
 {
     QEDIsAllocatedCB *cb = opaque;
     BDRVQEDState *s = cb->bs->opaque;
-    *cb->pnum = len / BDRV_SECTOR_SIZE;
+    *cb->pnum = len;
     switch (ret) {
     case QED_CLUSTER_FOUND:
-        offset |= qed_offset_into_cluster(s, cb->pos);
+        offset |= qed_offset_into_cluster(s, cb->pos) & BDRV_BLOCK_OFFSET_MASK;
         cb->status = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
         *cb->file = cb->bs->file->bs;
         break;
@@ -727,16 +727,18 @@ static void qed_is_allocated_cb(void *opaque, int ret, uint64_t offset, size_t l
     }
 }

-static int64_t coroutine_fn bdrv_qed_co_get_block_status(BlockDriverState *bs,
-                                                 int64_t sector_num,
-                                                 int nb_sectors, int *pnum,
-                                                 BlockDriverState **file)
+static int64_t coroutine_fn bdrv_qed_co_block_status(BlockDriverState *bs,
+                                                     bool mapping,
+                                                     int64_t pos,
+                                                     int64_t bytes,
+                                                     int64_t *pnum,
+                                                     BlockDriverState **file)
 {
     BDRVQEDState *s = bs->opaque;
-    size_t len = (size_t)nb_sectors * BDRV_SECTOR_SIZE;
+    size_t len;
     QEDIsAllocatedCB cb = {
         .bs = bs,
-        .pos = (uint64_t)sector_num * BDRV_SECTOR_SIZE,
+        .pos = pos,
         .status = BDRV_BLOCK_OFFSET_MASK,
         .pnum = pnum,
         .file = file,
@@ -1595,7 +1597,7 @@ static BlockDriver bdrv_qed = {
     .bdrv_child_perm          = bdrv_format_default_perms,
     .bdrv_create              = bdrv_qed_create,
     .bdrv_has_zero_init       = bdrv_has_zero_init_1,
-    .bdrv_co_get_block_status = bdrv_qed_co_get_block_status,
+    .bdrv_co_block_status     = bdrv_qed_co_block_status,
     .bdrv_co_readv            = bdrv_qed_co_readv,
     .bdrv_co_writev           = bdrv_qed_co_writev,
     .bdrv_co_pwrite_zeroes    = bdrv_qed_co_pwrite_zeroes,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 13/20] raw: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (11 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 12/20] qed: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 14/20] sheepdog: " Eric Blake
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the raw driver accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping
---
 block/raw-format.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/block/raw-format.c b/block/raw-format.c
index ab552c0954..22c7e980f2 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -250,17 +250,18 @@ fail:
     return ret;
 }

-static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
-                                            int64_t sector_num,
-                                            int nb_sectors, int *pnum,
-                                            BlockDriverState **file)
+static int64_t coroutine_fn raw_co_block_status(BlockDriverState *bs,
+                                                bool mapping,
+                                                int64_t offset,
+                                                int64_t bytes, int64_t *pnum,
+                                                BlockDriverState **file)
 {
     BDRVRawState *s = bs->opaque;
-    *pnum = nb_sectors;
+    *pnum = bytes;
     *file = bs->file->bs;
-    sector_num += s->offset / BDRV_SECTOR_SIZE;
+    offset += s->offset;
     return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
-           (sector_num << BDRV_SECTOR_BITS);
+        (offset & BDRV_BLOCK_OFFSET_MASK);
 }

 static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
@@ -496,7 +497,7 @@ BlockDriver bdrv_raw = {
     .bdrv_co_pwritev      = &raw_co_pwritev,
     .bdrv_co_pwrite_zeroes = &raw_co_pwrite_zeroes,
     .bdrv_co_pdiscard     = &raw_co_pdiscard,
-    .bdrv_co_get_block_status = &raw_co_get_block_status,
+    .bdrv_co_block_status = &raw_co_block_status,
     .bdrv_truncate        = &raw_truncate,
     .bdrv_getlength       = &raw_getlength,
     .has_variable_length  = true,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 14/20] sheepdog: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (12 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 13/20] raw: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 15/20] vdi: Avoid bitrot of debugging code Eric Blake
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel
  Cc: kwolf, jsnow, famz, qemu-block, Hitoshi Mitake, Liu Yuan,
	Jeff Cody, Max Reitz, open list:Sheepdog

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the sheepdog driver accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping flag
---
 block/sheepdog.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 696a71442a..09c431decc 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2989,18 +2989,17 @@ static coroutine_fn int sd_co_pdiscard(BlockDriverState *bs, int64_t offset,
 }

 static coroutine_fn int64_t
-sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
-                       int *pnum, BlockDriverState **file)
+sd_co_block_status(BlockDriverState *bs, bool mapping, int64_t offset,
+                   int64_t bytes, int64_t *pnum, BlockDriverState **file)
 {
     BDRVSheepdogState *s = bs->opaque;
     SheepdogInode *inode = &s->inode;
     uint32_t object_size = (UINT32_C(1) << inode->block_size_shift);
-    uint64_t offset = sector_num * BDRV_SECTOR_SIZE;
     unsigned long start = offset / object_size,
-                  end = DIV_ROUND_UP((sector_num + nb_sectors) *
-                                     BDRV_SECTOR_SIZE, object_size);
+                  end = DIV_ROUND_UP(offset + bytes, object_size);
     unsigned long idx;
-    int64_t ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
+    int64_t ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
+        (offset & BDRV_BLOCK_OFFSET_MASK);

     for (idx = start; idx < end; idx++) {
         if (inode->data_vdi_id[idx] == 0) {
@@ -3017,9 +3016,9 @@ sd_co_get_block_status(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
         }
     }

-    *pnum = (idx - start) * object_size / BDRV_SECTOR_SIZE;
-    if (*pnum > nb_sectors) {
-        *pnum = nb_sectors;
+    *pnum = (idx - start) * object_size;
+    if (*pnum > bytes) {
+        *pnum = bytes;
     }
     if (ret > 0 && ret & BDRV_BLOCK_OFFSET_VALID) {
         *file = bs;
@@ -3097,7 +3096,7 @@ static BlockDriver bdrv_sheepdog = {
     .bdrv_co_writev = sd_co_writev,
     .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
     .bdrv_co_pdiscard = sd_co_pdiscard,
-    .bdrv_co_get_block_status = sd_co_get_block_status,
+    .bdrv_co_block_status   = sd_co_block_status,

     .bdrv_snapshot_create   = sd_snapshot_create,
     .bdrv_snapshot_goto     = sd_snapshot_goto,
@@ -3133,7 +3132,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
     .bdrv_co_writev = sd_co_writev,
     .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
     .bdrv_co_pdiscard = sd_co_pdiscard,
-    .bdrv_co_get_block_status = sd_co_get_block_status,
+    .bdrv_co_block_status   = sd_co_block_status,

     .bdrv_snapshot_create   = sd_snapshot_create,
     .bdrv_snapshot_goto     = sd_snapshot_goto,
@@ -3169,7 +3168,7 @@ static BlockDriver bdrv_sheepdog_unix = {
     .bdrv_co_writev = sd_co_writev,
     .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,
     .bdrv_co_pdiscard = sd_co_pdiscard,
-    .bdrv_co_get_block_status = sd_co_get_block_status,
+    .bdrv_co_block_status   = sd_co_block_status,

     .bdrv_snapshot_create   = sd_snapshot_create,
     .bdrv_snapshot_goto     = sd_snapshot_goto,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 15/20] vdi: Avoid bitrot of debugging code
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (13 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 14/20] sheepdog: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 16/20] vdi: Switch to .bdrv_co_block_status() Eric Blake
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Stefan Weil, Max Reitz

Rework the debug define so that we always get -Wformat checking,
even when debugging is disabled.

Signed-off-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Weil <sw@weilnetz.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

---
v2: no change
---
 block/vdi.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/block/vdi.c b/block/vdi.c
index 8da5dfc897..6f83221ddc 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -86,12 +86,18 @@
 #define DEFAULT_CLUSTER_SIZE (1 * MiB)

 #if defined(CONFIG_VDI_DEBUG)
-#define logout(fmt, ...) \
-                fprintf(stderr, "vdi\t%-24s" fmt, __func__, ##__VA_ARGS__)
+#define VDI_DEBUG 1
 #else
-#define logout(fmt, ...) ((void)0)
+#define VDI_DEBUG 0
 #endif

+#define logout(fmt, ...) \
+    do {                                                                \
+        if (VDI_DEBUG) {                                                \
+            fprintf(stderr, "vdi\t%-24s" fmt, __func__, ##__VA_ARGS__); \
+        }                                                               \
+    } while (0)
+
 /* Image signature. */
 #define VDI_SIGNATURE 0xbeda107f

-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 16/20] vdi: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (14 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 15/20] vdi: Avoid bitrot of debugging code Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 17/20] vmdk: " Eric Blake
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Stefan Weil, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the vdi driver accordingly.  Note that the
TODO is already covered (the block layer guarantees bounds of its
requests), and that we can remove the now-unused s->block_sectors.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping flag
---
 block/vdi.c | 28 +++++++++++-----------------
 1 file changed, 11 insertions(+), 17 deletions(-)

diff --git a/block/vdi.c b/block/vdi.c
index 6f83221ddc..b571832127 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -171,8 +171,6 @@ typedef struct {
     uint32_t *bmap;
     /* Size of block (bytes). */
     uint32_t block_size;
-    /* Size of block (sectors). */
-    uint32_t block_sectors;
     /* First sector of block map. */
     uint32_t bmap_sector;
     /* VDI header (converted to host endianness). */
@@ -462,7 +460,6 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
     bs->total_sectors = header.disk_size / SECTOR_SIZE;

     s->block_size = header.block_size;
-    s->block_sectors = header.block_size / SECTOR_SIZE;
     s->bmap_sector = header.offset_bmap / SECTOR_SIZE;
     s->header = header;

@@ -508,23 +505,20 @@ static int vdi_reopen_prepare(BDRVReopenState *state,
     return 0;
 }

-static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int64_t coroutine_fn vdi_co_block_status(BlockDriverState *bs,
+                                                bool mapping,
+                                                int64_t offset, int64_t bytes,
+                                                int64_t *pnum,
+                                                BlockDriverState **file)
 {
-    /* TODO: Check for too large sector_num (in bdrv_is_allocated or here). */
     BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
-    size_t bmap_index = sector_num / s->block_sectors;
-    size_t sector_in_block = sector_num % s->block_sectors;
-    int n_sectors = s->block_sectors - sector_in_block;
+    size_t bmap_index = offset / s->block_size;
+    size_t index_in_block = offset % s->block_size;
     uint32_t bmap_entry = le32_to_cpu(s->bmap[bmap_index]);
-    uint64_t offset;
     int result;

-    logout("%p, %" PRId64 ", %d, %p\n", bs, sector_num, nb_sectors, pnum);
-    if (n_sectors > nb_sectors) {
-        n_sectors = nb_sectors;
-    }
-    *pnum = n_sectors;
+    logout("%p, %" PRId64 ", %" PRId64 ", %p\n", bs, offset, bytes, pnum);
+    *pnum = MIN(s->block_size, bytes);
     result = VDI_IS_ALLOCATED(bmap_entry);
     if (!result) {
         return 0;
@@ -532,7 +526,7 @@ static int64_t coroutine_fn vdi_co_get_block_status(BlockDriverState *bs,

     offset = s->header.offset_data +
                               (uint64_t)bmap_entry * s->block_size +
-                              sector_in_block * SECTOR_SIZE;
+                              (index_in_block & BDRV_BLOCK_OFFSET_MASK);
     *file = bs->file->bs;
     return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | offset;
 }
@@ -902,7 +896,7 @@ static BlockDriver bdrv_vdi = {
     .bdrv_child_perm          = bdrv_format_default_perms,
     .bdrv_create = vdi_create,
     .bdrv_has_zero_init = bdrv_has_zero_init_1,
-    .bdrv_co_get_block_status = vdi_co_get_block_status,
+    .bdrv_co_block_status = vdi_co_block_status,
     .bdrv_make_empty = vdi_make_empty,

     .bdrv_co_preadv     = vdi_co_preadv,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 17/20] vmdk: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (15 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 16/20] vdi: Switch to .bdrv_co_block_status() Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 18/20] vpc: " Eric Blake
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the vmdk driver accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to mapping flag
---
 block/vmdk.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index c665bcc977..68b9da419a 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1303,25 +1303,27 @@ static inline uint64_t vmdk_find_index_in_cluster(VmdkExtent *extent,
     return offset / BDRV_SECTOR_SIZE;
 }

-static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int64_t coroutine_fn vmdk_co_block_status(BlockDriverState *bs,
+                                                 bool mapping,
+                                                 int64_t offset, int64_t bytes,
+                                                 int64_t *pnum,
+                                                 BlockDriverState **file)
 {
     BDRVVmdkState *s = bs->opaque;
     int64_t index_in_cluster, n, ret;
-    uint64_t offset;
+    uint64_t cluster_offset;
     VmdkExtent *extent;

-    extent = find_extent(s, sector_num, NULL);
+    extent = find_extent(s, offset >> BDRV_SECTOR_BITS, NULL);
     if (!extent) {
         return 0;
     }
     qemu_co_mutex_lock(&s->lock);
-    ret = get_cluster_offset(bs, extent, NULL,
-                             sector_num * 512, false, &offset,
+    ret = get_cluster_offset(bs, extent, NULL, offset, false, &cluster_offset,
                              0, 0);
     qemu_co_mutex_unlock(&s->lock);

-    index_in_cluster = vmdk_find_index_in_cluster(extent, sector_num);
+    index_in_cluster = vmdk_find_offset_in_cluster(extent, offset);
     switch (ret) {
     case VMDK_ERROR:
         ret = -EIO;
@@ -1336,18 +1338,15 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs,
         ret = BDRV_BLOCK_DATA;
         if (!extent->compressed) {
             ret |= BDRV_BLOCK_OFFSET_VALID;
-            ret |= (offset + (index_in_cluster << BDRV_SECTOR_BITS))
+            ret |= (cluster_offset + index_in_cluster)
                     & BDRV_BLOCK_OFFSET_MASK;
         }
         *file = extent->file->bs;
         break;
     }

-    n = extent->cluster_sectors - index_in_cluster;
-    if (n > nb_sectors) {
-        n = nb_sectors;
-    }
-    *pnum = n;
+    n = extent->cluster_sectors * BDRV_SECTOR_SIZE - index_in_cluster;
+    *pnum = MIN(n, bytes);
     return ret;
 }

@@ -2393,7 +2392,7 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_close                   = vmdk_close,
     .bdrv_create                  = vmdk_create,
     .bdrv_co_flush_to_disk        = vmdk_co_flush,
-    .bdrv_co_get_block_status     = vmdk_co_get_block_status,
+    .bdrv_co_block_status         = vmdk_co_block_status,
     .bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
     .bdrv_has_zero_init           = vmdk_has_zero_init,
     .bdrv_get_specific_info       = vmdk_get_specific_info,
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 18/20] vpc: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (16 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 17/20] vmdk: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 19/20] vvfat: " Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 20/20] block: Drop unused .bdrv_co_get_block_status() Eric Blake
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the vpc driver accordingly.  Drop the now-unused
get_sector_offset().

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v3: rebase to master
v2: drop get_sector_offset() [Kevin], rebase to mapping flag
---
 block/vpc.c | 35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index 1576d7b595..2daa1db538 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -705,40 +705,42 @@ fail:
     return ret;
 }

-static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum, BlockDriverState **file)
+static int64_t coroutine_fn vpc_co_block_status(BlockDriverState *bs,
+                                                bool mapping,
+                                                int64_t offset, int64_t bytes,
+                                                int64_t *pnum,
+                                                BlockDriverState **file)
 {
     BDRVVPCState *s = bs->opaque;
     VHDFooter *footer = (VHDFooter*) s->footer_buf;
-    int64_t start, offset;
+    int64_t start, image_offset;
     bool allocated;
     int64_t ret;
     int n;

     if (be32_to_cpu(footer->type) == VHD_FIXED) {
-        *pnum = nb_sectors;
+        *pnum = bytes;
         *file = bs->file->bs;
         return BDRV_BLOCK_RAW | BDRV_BLOCK_OFFSET_VALID |
-               (sector_num << BDRV_SECTOR_BITS);
+               (offset & BDRV_BLOCK_OFFSET_MASK);
     }

     qemu_co_mutex_lock(&s->lock);

-    offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false, NULL);
-    start = offset;
-    allocated = (offset != -1);
+    image_offset = get_image_offset(bs, offset, false, NULL);
+    start = image_offset & BDRV_BLOCK_OFFSET_MASK;
+    allocated = (image_offset != -1);
     *pnum = 0;
     ret = 0;

     do {
         /* All sectors in a block are contiguous (without using the bitmap) */
-        n = ROUND_UP(sector_num + 1, s->block_size / BDRV_SECTOR_SIZE)
-          - sector_num;
-        n = MIN(n, nb_sectors);
+        n = ROUND_UP(offset + 1, s->block_size) - offset;
+        n = MIN(n, bytes);

         *pnum += n;
-        sector_num += n;
-        nb_sectors -= n;
+        offset += n;
+        bytes -= n;
         /* *pnum can't be greater than one block for allocated
          * sectors since there is always a bitmap in between. */
         if (allocated) {
@@ -746,11 +748,10 @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
             ret = BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID | start;
             break;
         }
-        if (nb_sectors == 0) {
+        if (bytes == 0) {
             break;
         }
-        offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false,
-                                  NULL);
+        image_offset = get_image_offset(bs, offset, false, NULL);
     } while (offset == -1);

     qemu_co_mutex_unlock(&s->lock);
@@ -1097,7 +1098,7 @@ static BlockDriver bdrv_vpc = {

     .bdrv_co_preadv             = vpc_co_preadv,
     .bdrv_co_pwritev            = vpc_co_pwritev,
-    .bdrv_co_get_block_status   = vpc_co_get_block_status,
+    .bdrv_co_block_status       = vpc_co_block_status,

     .bdrv_get_info          = vpc_get_info,

-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 19/20] vvfat: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (17 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 18/20] vpc: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 20/20] block: Drop unused .bdrv_co_get_block_status() Eric Blake
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Update the vvfat driver accordingly.  Note that we
can rely on the block driver having already clamped limits to our
block size, and simplify accordingly.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to earlier changes, simplify
---
 block/vvfat.c | 16 +++++++---------
 1 file changed, 7 insertions(+), 9 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index c54fa94651..6a08d68ae3 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -3090,15 +3090,13 @@ vvfat_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
     return ret;
 }

-static int64_t coroutine_fn vvfat_co_get_block_status(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *n, BlockDriverState **file)
+static int64_t coroutine_fn vvfat_co_block_status(BlockDriverState *bs,
+                                                  bool mapping,
+                                                  int64_t offset,
+                                                  int64_t bytes, int64_t *n,
+                                                  BlockDriverState **file)
 {
-    *n = bs->total_sectors - sector_num;
-    if (*n > nb_sectors) {
-        *n = nb_sectors;
-    } else if (*n < 0) {
-        return 0;
-    }
+    *n = bytes;
     return BDRV_BLOCK_DATA;
 }

@@ -3258,7 +3256,7 @@ static BlockDriver bdrv_vvfat = {

     .bdrv_co_preadv         = vvfat_co_preadv,
     .bdrv_co_pwritev        = vvfat_co_pwritev,
-    .bdrv_co_get_block_status = vvfat_co_get_block_status,
+    .bdrv_co_block_status   = vvfat_co_block_status,
 };

 static void bdrv_vvfat_init(void)
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* [Qemu-devel] [PATCH v3 20/20] block: Drop unused .bdrv_co_get_block_status()
  2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
                   ` (18 preceding siblings ...)
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 19/20] vvfat: " Eric Blake
@ 2017-09-14 14:40 ` Eric Blake
  19 siblings, 0 replies; 24+ messages in thread
From: Eric Blake @ 2017-09-14 14:40 UTC (permalink / raw)
  To: qemu-devel; +Cc: kwolf, jsnow, famz, qemu-block, Stefan Hajnoczi, Max Reitz

We are gradually moving away from sector-based interfaces, towards
byte-based.  Now that all drivers have been updated to provide the
byte-based .bdrv_co_block_status(), we can delete the sector-based
interface.

Signed-off-by: Eric Blake <eblake@redhat.com>

---
v2: rebase to earlier changes
---
 include/block/block_int.h |  3 ---
 block/io.c                | 23 +----------------------
 2 files changed, 1 insertion(+), 25 deletions(-)

diff --git a/include/block/block_int.h b/include/block/block_int.h
index ba5c2f9f1f..0bb5e9ebe0 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -212,9 +212,6 @@ struct BlockDriver {
      * (favor larger *pnum).  The block layer guarantees input aligned
      * to request_alignment, as well as non-NULL pnum and file.
      */
-    int64_t coroutine_fn (*bdrv_co_get_block_status)(BlockDriverState *bs,
-        int64_t sector_num, int nb_sectors, int *pnum,
-        BlockDriverState **file);
     int64_t coroutine_fn (*bdrv_co_block_status)(BlockDriverState *bd,
         bool mapping, int64_t offset, int64_t bytes, int64_t *pnum,
         BlockDriverState **file);
diff --git a/block/io.c b/block/io.c
index 85c01b2800..e58da6f81a 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1796,7 +1796,7 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
         bytes = n;
     }

-    if (!bs->drv->bdrv_co_get_block_status && !bs->drv->bdrv_co_block_status) {
+    if (!bs->drv->bdrv_co_block_status) {
         *pnum = bytes;
         ret = BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED;
         if (offset + bytes == total_size) {
@@ -1817,29 +1817,9 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,

     /* Round out to request_alignment boundaries */
     align = bs->bl.request_alignment;
-    if (bs->drv->bdrv_co_get_block_status && align < BDRV_SECTOR_SIZE) {
-        align = BDRV_SECTOR_SIZE;
-    }
     aligned_offset = QEMU_ALIGN_DOWN(offset, align);
     aligned_bytes = ROUND_UP(offset + bytes, align) - aligned_offset;

-    if (bs->drv->bdrv_co_get_block_status) {
-        int count; /* sectors */
-
-        assert(QEMU_IS_ALIGNED(aligned_offset | aligned_bytes,
-                               BDRV_SECTOR_SIZE));
-        ret = bs->drv->bdrv_co_get_block_status(
-            bs, aligned_offset >> BDRV_SECTOR_BITS,
-            MIN(INT_MAX, aligned_bytes) >> BDRV_SECTOR_BITS, &count,
-            &local_file);
-        if (ret < 0) {
-            *pnum = 0;
-            goto out;
-        }
-        *pnum = count * BDRV_SECTOR_SIZE;
-        goto refine;
-    }
-
     ret = bs->drv->bdrv_co_block_status(bs, mapping, aligned_offset,
                                         aligned_bytes, pnum, &local_file);
     if (ret < 0) {
@@ -1856,7 +1836,6 @@ static int64_t coroutine_fn bdrv_co_block_status(BlockDriverState *bs,
         *pnum = total_size - aligned_offset;
     }

- refine:
     /* Clamp pnum and ret to original request */
     assert(QEMU_IS_ALIGNED(*pnum, align));
     *pnum -= offset - aligned_offset;
-- 
2.13.5

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v3 03/20] file-posix: Switch to .bdrv_co_block_status()
  2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 03/20] file-posix: Switch " Eric Blake
@ 2017-09-20  9:57   ` Fam Zheng
  2017-09-20 13:47     ` Eric Blake
  0 siblings, 1 reply; 24+ messages in thread
From: Fam Zheng @ 2017-09-20  9:57 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, kwolf, jsnow, qemu-block, Max Reitz

On Thu, 09/14 09:40, Eric Blake wrote:
> We are gradually moving away from sector-based interfaces, towards
> byte-based.  Update the file protocol driver accordingly.  In mapping
> mode, note that the entire file is reported as allocated, so we can
> take a shortcut and skip lseek().
> 
> Signed-off-by: Eric Blake <eblake@redhat.com>
> 
> ---
> v2: tweak comment, add mapping support
> ---
>  block/file-posix.c | 57 ++++++++++++++++++++++++++++++------------------------
>  1 file changed, 32 insertions(+), 25 deletions(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 72ecfbb0e0..6813059867 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -2107,24 +2107,25 @@ static int find_allocation(BlockDriverState *bs, off_t start,
>  }
> 
>  /*
> - * Returns the allocation status of the specified sectors.
> + * Returns the allocation status of the specified offset.
>   *
> - * If 'sector_num' is beyond the end of the disk image the return value is 0
> + * If 'offset' is beyond the end of the disk image the return value is 0
>   * and 'pnum' is set to 0.
>   *
> - * 'pnum' is set to the number of sectors (including and immediately following
> - * the specified sector) that are known to be in the same
> + * 'pnum' is set to the number of bytes (including and immediately following
> + * the specified offset) that are known to be in the same
>   * allocated/unallocated state.
>   *
> - * 'nb_sectors' is the max value 'pnum' should be set to.  If nb_sectors goes
> + * 'bytes' is the max value 'pnum' should be set to.  If bytes goes
>   * beyond the end of the disk image it will be clamped.
>   */
> -static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
> -                                                    int64_t sector_num,
> -                                                    int nb_sectors, int *pnum,
> -                                                    BlockDriverState **file)
> +static int64_t coroutine_fn raw_co_block_status(BlockDriverState *bs,
> +                                                bool mapping,
> +                                                int64_t offset,
> +                                                int64_t bytes, int64_t *pnum,
> +                                                BlockDriverState **file)
>  {
> -    off_t start, data = 0, hole = 0;
> +    off_t data = 0, hole = 0;
>      int64_t total_size;
>      int ret;
> 
> @@ -2133,39 +2134,45 @@ static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
>          return ret;
>      }
> 
> -    start = sector_num * BDRV_SECTOR_SIZE;
>      total_size = bdrv_getlength(bs);
>      if (total_size < 0) {
>          return total_size;
> -    } else if (start >= total_size) {
> +    } else if (offset >= total_size) {
>          *pnum = 0;
>          return 0;
> -    } else if (start + nb_sectors * BDRV_SECTOR_SIZE > total_size) {
> -        nb_sectors = DIV_ROUND_UP(total_size - start, BDRV_SECTOR_SIZE);
> +    } else if (offset + bytes > total_size) {
> +        bytes = total_size - offset;
>      }
> 
> -    ret = find_allocation(bs, start, &data, &hole);
> +    if (!mapping) {
> +        *pnum = bytes;
> +        *file = bs;
> +        return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
> +            (offset & BDRV_BLOCK_OFFSET_MASK);
> +    }

I may be missing something, because the last time I tried to understand the
rationale behind "mapping" was already some time ago: shouldn't we still
distinguish hole and data? What will omitting BDRV_BLOCK_ZERO help?

Fam

> +
> +    ret = find_allocation(bs, offset, &data, &hole);
>      if (ret == -ENXIO) {
>          /* Trailing hole */
> -        *pnum = nb_sectors;
> +        *pnum = bytes;
>          ret = BDRV_BLOCK_ZERO;
>      } else if (ret < 0) {
>          /* No info available, so pretend there are no holes */
> -        *pnum = nb_sectors;
> +        *pnum = bytes;
>          ret = BDRV_BLOCK_DATA;
> -    } else if (data == start) {
> -        /* On a data extent, compute sectors to the end of the extent,
> +    } else if (data == offset) {
> +        /* On a data extent, compute bytes to the end of the extent,
>           * possibly including a partial sector at EOF. */
> -        *pnum = MIN(nb_sectors, DIV_ROUND_UP(hole - start, BDRV_SECTOR_SIZE));
> +        *pnum = MIN(bytes, hole - offset);
>          ret = BDRV_BLOCK_DATA;
>      } else {
> -        /* On a hole, compute sectors to the beginning of the next extent.  */
> -        assert(hole == start);
> -        *pnum = MIN(nb_sectors, (data - start) / BDRV_SECTOR_SIZE);
> +        /* On a hole, compute bytes to the beginning of the next extent.  */
> +        assert(hole == offset);
> +        *pnum = MIN(bytes, data - offset);
>          ret = BDRV_BLOCK_ZERO;
>      }
>      *file = bs;
> -    return ret | BDRV_BLOCK_OFFSET_VALID | start;
> +    return ret | BDRV_BLOCK_OFFSET_VALID | (offset & BDRV_BLOCK_OFFSET_MASK);
>  }
> 
>  static coroutine_fn BlockAIOCB *raw_aio_pdiscard(BlockDriverState *bs,
> @@ -2259,7 +2266,7 @@ BlockDriver bdrv_file = {
>      .bdrv_close = raw_close,
>      .bdrv_create = raw_create,
>      .bdrv_has_zero_init = bdrv_has_zero_init_1,
> -    .bdrv_co_get_block_status = raw_co_get_block_status,
> +    .bdrv_co_block_status = raw_co_block_status,
>      .bdrv_co_pwrite_zeroes = raw_co_pwrite_zeroes,
> 
>      .bdrv_co_preadv         = raw_co_preadv,
> -- 
> 2.13.5
> 

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v3 03/20] file-posix: Switch to .bdrv_co_block_status()
  2017-09-20  9:57   ` Fam Zheng
@ 2017-09-20 13:47     ` Eric Blake
  2017-09-22  5:54       ` Fam Zheng
  0 siblings, 1 reply; 24+ messages in thread
From: Eric Blake @ 2017-09-20 13:47 UTC (permalink / raw)
  To: Fam Zheng; +Cc: qemu-devel, kwolf, jsnow, qemu-block, Max Reitz

[-- Attachment #1: Type: text/plain, Size: 2696 bytes --]

On 09/20/2017 04:57 AM, Fam Zheng wrote:
> On Thu, 09/14 09:40, Eric Blake wrote:
>> We are gradually moving away from sector-based interfaces, towards
>> byte-based.  Update the file protocol driver accordingly.  In mapping
>> mode, note that the entire file is reported as allocated, so we can
>> take a shortcut and skip lseek().
>>
>> Signed-off-by: Eric Blake <eblake@redhat.com>
>>

>>
>> -    ret = find_allocation(bs, start, &data, &hole);
>> +    if (!mapping) {
>> +        *pnum = bytes;
>> +        *file = bs;
>> +        return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
>> +            (offset & BDRV_BLOCK_OFFSET_MASK);
>> +    }
> 
> I may be missing something, because the last time I tried to understand the
> rationale behind "mapping" was already some time ago: shouldn't we still
> distinguish hole and data? What will omitting BDRV_BLOCK_ZERO help?

Hmm, the commit message is slightly off (in part, because I switched the
sense of the bool flag between series revisions, but did not properly
update the commit text to match).  In mapping mode, we want to return as
much information as possible (the client is something like 'qemu-img
map'), including where the holes lie.  But when we are NOT in mapping
mode, we care more about learning which portions of the file are
described in the current layer of the backing chain, rather than
delegating to another layer, regardless of whether the read will see
data or zeroes.  By the time we are at the POSIX file protocol layer, we
know that every byte in the file system/block device has a 1:1 mapping
to the bytes that the guest will read (we do not delegate to any backing
file), so we can simply report the entire remainder of the file as
allocated without worrying about holes.

Here's where the mapping flag was added and semantics documented (in
series 3; whereas the current email is series 4):
https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg03542.html

So what I really need to do is fix the commit message to read:

In mapping mode, we must report as much information as possible about
where holes can be found; but when we don't care about mapping, the user
is more interested in how much of the guest view will come from the
current layer rather than delegating to some other BDS, and we can take
the shortcut that all of the remainder of the file fits that
description, and therefore take a shortcut and skip lseek() for a larger
*pnum result.

(the same comment probably applies to several other patches in the series)

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 619 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [Qemu-devel] [PATCH v3 03/20] file-posix: Switch to .bdrv_co_block_status()
  2017-09-20 13:47     ` Eric Blake
@ 2017-09-22  5:54       ` Fam Zheng
  0 siblings, 0 replies; 24+ messages in thread
From: Fam Zheng @ 2017-09-22  5:54 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel, kwolf, jsnow, qemu-block, Max Reitz

On Wed, 09/20 08:47, Eric Blake wrote:
> On 09/20/2017 04:57 AM, Fam Zheng wrote:
> > On Thu, 09/14 09:40, Eric Blake wrote:
> >> We are gradually moving away from sector-based interfaces, towards
> >> byte-based.  Update the file protocol driver accordingly.  In mapping
> >> mode, note that the entire file is reported as allocated, so we can
> >> take a shortcut and skip lseek().
> >>
> >> Signed-off-by: Eric Blake <eblake@redhat.com>
> >>
> 
> >>
> >> -    ret = find_allocation(bs, start, &data, &hole);
> >> +    if (!mapping) {
> >> +        *pnum = bytes;
> >> +        *file = bs;
> >> +        return BDRV_BLOCK_DATA | BDRV_BLOCK_OFFSET_VALID |
> >> +            (offset & BDRV_BLOCK_OFFSET_MASK);
> >> +    }
> > 
> > I may be missing something, because the last time I tried to understand the
> > rationale behind "mapping" was already some time ago: shouldn't we still
> > distinguish hole and data? What will omitting BDRV_BLOCK_ZERO help?
> 
> Hmm, the commit message is slightly off (in part, because I switched the
> sense of the bool flag between series revisions, but did not properly
> update the commit text to match).  In mapping mode, we want to return as
> much information as possible (the client is something like 'qemu-img
> map'), including where the holes lie.  But when we are NOT in mapping
> mode, we care more about learning which portions of the file are
> described in the current layer of the backing chain, rather than
> delegating to another layer, regardless of whether the read will see
> data or zeroes.  By the time we are at the POSIX file protocol layer, we
> know that every byte in the file system/block device has a 1:1 mapping
> to the bytes that the guest will read (we do not delegate to any backing
> file), so we can simply report the entire remainder of the file as
> allocated without worrying about holes.

Thanks, it would be good if this explanation can be added to the comment of
"mapping" parameter, so it's easy to understand the actual intention in the
future.

> 
> Here's where the mapping flag was added and semantics documented (in
> series 3; whereas the current email is series 4):
> https://lists.gnu.org/archive/html/qemu-devel/2017-09/msg03542.html
> 
> So what I really need to do is fix the commit message to read:
> 
> In mapping mode, we must report as much information as possible about
> where holes can be found; but when we don't care about mapping, the user
> is more interested in how much of the guest view will come from the
> current layer rather than delegating to some other BDS, and we can take
> the shortcut that all of the remainder of the file fits that
> description, and therefore take a shortcut and skip lseek() for a larger
> *pnum result.
> 
> (the same comment probably applies to several other patches in the series)
> 

Fam

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2017-09-22  5:55 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-09-14 14:40 [Qemu-devel] [PATCH v3 00/20] add byte-based block_status driver callbacks Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 01/20] block: Add .bdrv_co_block_status() callback Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 02/20] block: Switch passthrough drivers to .bdrv_co_block_status() Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 03/20] file-posix: Switch " Eric Blake
2017-09-20  9:57   ` Fam Zheng
2017-09-20 13:47     ` Eric Blake
2017-09-22  5:54       ` Fam Zheng
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 04/20] gluster: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 05/20] iscsi: Switch cluster_sectors to byte-based Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 06/20] iscsi: Switch iscsi_allocmap_update() " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 07/20] iscsi: Switch to .bdrv_co_block_status() Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 08/20] null: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 09/20] parallels: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 10/20] qcow: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 11/20] qcow2: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 12/20] qed: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 13/20] raw: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 14/20] sheepdog: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 15/20] vdi: Avoid bitrot of debugging code Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 16/20] vdi: Switch to .bdrv_co_block_status() Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 17/20] vmdk: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 18/20] vpc: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 19/20] vvfat: " Eric Blake
2017-09-14 14:40 ` [Qemu-devel] [PATCH v3 20/20] block: Drop unused .bdrv_co_get_block_status() Eric Blake

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.