qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5 00/11] block: file-posix queue
@ 2021-06-24 18:04 Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 01/11] file-posix: fix max_iov for /dev/sg devices Paolo Bonzini
                   ` (11 more replies)
  0 siblings, 12 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

New patches:
- 3/4 (for review comments),
- 9 (split for ease of review),
- 11 (new bugfix)

v1->v2: add missing patch

v2->v3: add max_hw_transfer to BlockLimits

v3->v4: fix compilation after patch 1, tweak commit messages according
        to Vladimir's review

v4->v5: round down max_transfer and max_hw_transfer to request alignment
        checkpatch fixes
        return -ENOTSUP, -not -EIO if block limits ioctls fail
        handle host_cdrom like host_device in QAPI
        split "block: try BSD disk size ioctls one after another"
        new bugfix patch "file-posix: handle EINTR during ioctl"

Joelle van Dyne (3):
  block: feature detection for host block support
  block: check for sys/disk.h
  block: detect DKIOCGETBLOCKCOUNT/SIZE before use

Paolo Bonzini (8):
  file-posix: fix max_iov for /dev/sg devices
  scsi-generic: pass max_segments via max_iov field in BlockLimits
  osdep: provide ROUND_DOWN macro
  block-backend: align max_transfer to request alignment
  block: add max_hw_transfer to BlockLimits
  file-posix: try BLKSECTGET on block devices too, do not round to power of 2
  block: try BSD disk size ioctls one after another
  file-posix: handle EINTR during ioctl

 block.c                        |   2 +-
 block/block-backend.c          |  19 ++++-
 block/file-posix.c             | 144 ++++++++++++++++++++-------------
 block/io.c                     |   2 +
 hw/scsi/scsi-generic.c         |   6 +-
 include/block/block_int.h      |   7 ++
 include/qemu/osdep.h           |  28 +++++--
 include/sysemu/block-backend.h |   1 +
 meson.build                    |   7 +-
 qapi/block-core.json           |  14 +++-
 10 files changed, 156 insertions(+), 74 deletions(-)

-- 
2.31.1



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

* [PATCH 01/11] file-posix: fix max_iov for /dev/sg devices
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 02/11] scsi-generic: pass max_segments via max_iov field in BlockLimits Paolo Bonzini
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

Even though it was only called for devices that have bs->sg set (which
must be character devices), sg_get_max_segments looked at /sys/dev/block
which only works for block devices.

On Linux the sg driver has its own way to provide the maximum number of
iovecs in a scatter/gather list, so add support for it.  The block device
path is kept because it will be reinstated in the next patches.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 block/file-posix.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/block/file-posix.c b/block/file-posix.c
index b3fbb9bd63..b8dc19ce1a 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1178,6 +1178,17 @@ static int sg_get_max_segments(int fd)
         goto out;
     }
 
+    if (S_ISCHR(st.st_mode)) {
+        if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
+            return ret;
+        }
+        return -ENOTSUP;
+    }
+
+    if (!S_ISBLK(st.st_mode)) {
+        return -ENOTSUP;
+    }
+
     sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
                                 major(st.st_rdev), minor(st.st_rdev));
     sysfd = open(sysfspath, O_RDONLY);
-- 
2.31.1




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

* [PATCH 02/11] scsi-generic: pass max_segments via max_iov field in BlockLimits
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 01/11] file-posix: fix max_iov for /dev/sg devices Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 03/11] osdep: provide ROUND_DOWN macro Paolo Bonzini
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

I/O to a disk via read/write is not limited by the number of segments allowed
by the host adapter; the kernel can split requests if needed, and the limit
imposed by the host adapter can be very low (256k or so) to avoid that SG_IO
returns EINVAL if memory is heavily fragmented.

Since this value is only interesting for SG_IO-based I/O, do not include
it in the max_transfer and only take it into account when patching the
block limits VPD page in the scsi-generic device.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
 block/file-posix.c     | 3 +--
 hw/scsi/scsi-generic.c | 6 ++++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index b8dc19ce1a..6db690baf2 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1237,8 +1237,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 
         ret = sg_get_max_segments(s->fd);
         if (ret > 0) {
-            bs->bl.max_transfer = MIN(bs->bl.max_transfer,
-                                      ret * qemu_real_host_page_size);
+            bs->bl.max_iov = ret;
         }
     }
 
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 40e039864f..b6c4143dc7 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -179,10 +179,12 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
         (r->req.cmd.buf[1] & 0x01)) {
         page = r->req.cmd.buf[2];
         if (page == 0xb0) {
-            uint32_t max_transfer =
-                blk_get_max_transfer(s->conf.blk) / s->blocksize;
+            uint32_t max_transfer = blk_get_max_transfer(s->conf.blk);
+            uint32_t max_iov = blk_get_max_iov(s->conf.blk);
 
             assert(max_transfer);
+            max_transfer = MIN_NON_ZERO(max_transfer, max_iov * qemu_real_host_page_size)
+                / s->blocksize;
             stl_be_p(&r->buf[8], max_transfer);
             /* Also take care of the opt xfer len. */
             stl_be_p(&r->buf[12],
-- 
2.31.1




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

* [PATCH 03/11] osdep: provide ROUND_DOWN macro
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 01/11] file-posix: fix max_iov for /dev/sg devices Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 02/11] scsi-generic: pass max_segments via max_iov field in BlockLimits Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  7:42   ` Max Reitz
  2021-06-25  8:26   ` Philippe Mathieu-Daudé
  2021-06-24 18:04 ` [PATCH 04/11] block-backend: align max_transfer to request alignment Paolo Bonzini
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

osdep.h provides a ROUND_UP macro to hide bitwise operations for the
purpose of rounding a number up to a power of two; add a ROUND_DOWN
macro that does the same with truncation towards zero.

While at it, change the formatting of some comments.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/osdep.h | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 0a54bf7be8..c3656b755a 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -319,11 +319,16 @@ extern "C" {
     })
 #endif
 
-/* Round number down to multiple */
+/*
+ * Round number down to multiple. Safe when m is not a power of 2 (see
+ * ROUND_DOWN for a faster version when a power of 2 is guaranteed).
+ */
 #define QEMU_ALIGN_DOWN(n, m) ((n) / (m) * (m))
 
-/* Round number up to multiple. Safe when m is not a power of 2 (see
- * ROUND_UP for a faster version when a power of 2 is guaranteed) */
+/*
+ * Round number up to multiple. Safe when m is not a power of 2 (see
+ * ROUND_UP for a faster version when a power of 2 is guaranteed).
+ */
 #define QEMU_ALIGN_UP(n, m) QEMU_ALIGN_DOWN((n) + (m) - 1, (m))
 
 /* Check if n is a multiple of m */
@@ -340,11 +345,22 @@ extern "C" {
 /* Check if pointer p is n-bytes aligned */
 #define QEMU_PTR_IS_ALIGNED(p, n) QEMU_IS_ALIGNED((uintptr_t)(p), (n))
 
-/* Round number up to multiple. Requires that d be a power of 2 (see
+/*
+ * Round number down to multiple. Requires that d be a power of 2 (see
  * QEMU_ALIGN_UP for a safer but slower version on arbitrary
- * numbers); works even if d is a smaller type than n.  */
+ * numbers); works even if d is a smaller type than n.
+ */
+#ifndef ROUND_DOWN
+#define ROUND_DOWN(n, d) ((n) & -(0 ? (n) : (d)))
+#endif
+
+/*
+ * Round number up to multiple. Requires that d be a power of 2 (see
+ * QEMU_ALIGN_UP for a safer but slower version on arbitrary
+ * numbers); works even if d is a smaller type than n.
+ */
 #ifndef ROUND_UP
-#define ROUND_UP(n, d) (((n) + (d) - 1) & -(0 ? (n) : (d)))
+#define ROUND_UP(n, d) ROUND_DOWN((n) + (d) - 1, (d))
 #endif
 
 #ifndef DIV_ROUND_UP
-- 
2.31.1




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

* [PATCH 04/11] block-backend: align max_transfer to request alignment
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (2 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 03/11] osdep: provide ROUND_DOWN macro Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  7:52   ` Max Reitz
  2021-06-24 18:04 ` [PATCH 05/11] block: add max_hw_transfer to BlockLimits Paolo Bonzini
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

Block device requests must be aligned to bs->bl.request_alignment.
It makes sense for drivers to align bs->bl.max_transfer the same
way; however when there is no specified limit, blk_get_max_transfer
just returns INT_MAX.  Since the contract of the function does not
specify that INT_MAX means "no maximum", just align the outcome
of the function (whether INT_MAX or bs->bl.max_transfer) before
returning it.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/block-backend.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 15f1ea4288..6e37582740 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1957,12 +1957,12 @@ uint32_t blk_get_request_alignment(BlockBackend *blk)
 uint32_t blk_get_max_transfer(BlockBackend *blk)
 {
     BlockDriverState *bs = blk_bs(blk);
-    uint32_t max = 0;
+    uint32_t max = INT_MAX;
 
     if (bs) {
-        max = bs->bl.max_transfer;
+        max = MIN_NON_ZERO(max, bs->bl.max_transfer);
     }
-    return MIN_NON_ZERO(max, INT_MAX);
+    return ROUND_DOWN(max, blk_get_request_alignment(blk));
 }
 
 int blk_get_max_iov(BlockBackend *blk)
-- 
2.31.1




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

* [PATCH 05/11] block: add max_hw_transfer to BlockLimits
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (3 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 04/11] block-backend: align max_transfer to request alignment Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  7:58   ` Max Reitz
  2021-06-24 18:04 ` [PATCH 06/11] file-posix: try BLKSECTGET on block devices too, do not round to power of 2 Paolo Bonzini
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

For block host devices, I/O can happen through either the kernel file
descriptor I/O system calls (preadv/pwritev, io_submit, io_uring)
or the SCSI passthrough ioctl SG_IO.

In the latter case, the size of each transfer can be limited by the
HBA, while for file descriptor I/O the kernel is able to split and
merge I/O in smaller pieces as needed.  Applying the HBA limits to
file descriptor I/O results in more system calls and suboptimal
performance, so this patch splits the max_transfer limit in two:
max_transfer remains valid and is used in general, while max_hw_transfer
is limited to the maximum hardware size.  max_hw_transfer can then be
included by the scsi-generic driver in the block limits page, to ensure
that the stricter hardware limit is used.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/block-backend.c          | 13 +++++++++++++
 block/file-posix.c             |  2 +-
 block/io.c                     |  2 ++
 hw/scsi/scsi-generic.c         |  2 +-
 include/block/block_int.h      |  7 +++++++
 include/sysemu/block-backend.h |  1 +
 6 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 6e37582740..deb55c272e 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1953,6 +1953,19 @@ uint32_t blk_get_request_alignment(BlockBackend *blk)
     return bs ? bs->bl.request_alignment : BDRV_SECTOR_SIZE;
 }
 
+/* Returns the maximum hardware transfer length, in bytes; guaranteed nonzero */
+uint64_t blk_get_max_hw_transfer(BlockBackend *blk)
+{
+    BlockDriverState *bs = blk_bs(blk);
+    uint64_t max = INT_MAX;
+
+    if (bs) {
+        max = MIN_NON_ZERO(max, bs->bl.max_hw_transfer);
+        max = MIN_NON_ZERO(max, bs->bl.max_transfer);
+    }
+    return ROUND_DOWN(max, blk_get_request_alignment(blk));
+}
+
 /* Returns the maximum transfer length, in bytes; guaranteed nonzero */
 uint32_t blk_get_max_transfer(BlockBackend *blk)
 {
diff --git a/block/file-posix.c b/block/file-posix.c
index 6db690baf2..88e58d2863 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1232,7 +1232,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
         int ret = sg_get_max_transfer_length(s->fd);
 
         if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
-            bs->bl.max_transfer = pow2floor(ret);
+            bs->bl.max_hw_transfer = pow2floor(ret);
         }
 
         ret = sg_get_max_segments(s->fd);
diff --git a/block/io.c b/block/io.c
index 323854d063..dd93364258 100644
--- a/block/io.c
+++ b/block/io.c
@@ -127,6 +127,8 @@ static void bdrv_merge_limits(BlockLimits *dst, const BlockLimits *src)
 {
     dst->opt_transfer = MAX(dst->opt_transfer, src->opt_transfer);
     dst->max_transfer = MIN_NON_ZERO(dst->max_transfer, src->max_transfer);
+    dst->max_hw_transfer = MIN_NON_ZERO(dst->max_hw_transfer,
+                                        src->max_hw_transfer);
     dst->opt_mem_alignment = MAX(dst->opt_mem_alignment,
                                  src->opt_mem_alignment);
     dst->min_mem_alignment = MAX(dst->min_mem_alignment,
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index b6c4143dc7..665baf900e 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -179,7 +179,7 @@ static int scsi_handle_inquiry_reply(SCSIGenericReq *r, SCSIDevice *s, int len)
         (r->req.cmd.buf[1] & 0x01)) {
         page = r->req.cmd.buf[2];
         if (page == 0xb0) {
-            uint32_t max_transfer = blk_get_max_transfer(s->conf.blk);
+            uint64_t max_transfer = blk_get_max_hw_transfer(s->conf.blk);
             uint32_t max_iov = blk_get_max_iov(s->conf.blk);
 
             assert(max_transfer);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 057d88b1fc..f1a54db0f8 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -695,6 +695,13 @@ typedef struct BlockLimits {
      * clamped down. */
     uint32_t max_transfer;
 
+    /* Maximal hardware transfer length in bytes.  Applies whenever
+     * transfers to the device bypass the kernel I/O scheduler, for
+     * example with SG_IO.  If larger than max_transfer or if zero,
+     * blk_get_max_hw_transfer will fall back to max_transfer.
+     */
+    uint64_t max_hw_transfer;
+
     /* memory alignment, in bytes so that no bounce buffer is needed */
     size_t min_mem_alignment;
 
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 5423e3d9c6..9ac5f7bbd3 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -208,6 +208,7 @@ void blk_eject(BlockBackend *blk, bool eject_flag);
 int blk_get_flags(BlockBackend *blk);
 uint32_t blk_get_request_alignment(BlockBackend *blk);
 uint32_t blk_get_max_transfer(BlockBackend *blk);
+uint64_t blk_get_max_hw_transfer(BlockBackend *blk);
 int blk_get_max_iov(BlockBackend *blk);
 void blk_set_guest_block_size(BlockBackend *blk, int align);
 void *blk_try_blockalign(BlockBackend *blk, size_t size);
-- 
2.31.1




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

* [PATCH 06/11] file-posix: try BLKSECTGET on block devices too, do not round to power of 2
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (4 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 05/11] block: add max_hw_transfer to BlockLimits Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  8:19   ` Max Reitz
  2021-06-24 18:04 ` [PATCH 07/11] block: feature detection for host block support Paolo Bonzini
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

bs->sg is only true for character devices, but block devices can also
be used with scsi-block and scsi-generic.  Unfortunately BLKSECTGET
returns bytes in an int for /dev/sgN devices, and sectors in a short
for block devices, so account for that in the code.

The maximum transfer also need not be a power of 2 (for example I have
seen disks with 1280 KiB maximum transfer) so there's no need to pass
the result through pow2floor.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/file-posix.c | 67 ++++++++++++++++++++++++++--------------------
 1 file changed, 38 insertions(+), 29 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 88e58d2863..ea102483b0 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1147,22 +1147,27 @@ static void raw_reopen_abort(BDRVReopenState *state)
     s->reopen_state = NULL;
 }
 
-static int sg_get_max_transfer_length(int fd)
+static int hdev_get_max_hw_transfer(int fd, struct stat *st)
 {
 #ifdef BLKSECTGET
-    int max_bytes = 0;
-
-    if (ioctl(fd, BLKSECTGET, &max_bytes) == 0) {
-        return max_bytes;
+    if (S_ISBLK(st->st_mode)) {
+        unsigned short max_sectors = 0;
+        if (ioctl(fd, BLKSECTGET, &max_sectors) == 0) {
+            return max_sectors * 512;
+        }
     } else {
-        return -errno;
+        int max_bytes = 0;
+        if (ioctl(fd, BLKSECTGET, &max_bytes) == 0) {
+            return max_bytes;
+        }
     }
+    return -errno;
 #else
     return -ENOSYS;
 #endif
 }
 
-static int sg_get_max_segments(int fd)
+static int hdev_get_max_segments(int fd, struct stat *st)
 {
 #ifdef CONFIG_LINUX
     char buf[32];
@@ -1171,26 +1176,20 @@ static int sg_get_max_segments(int fd)
     int ret;
     int sysfd = -1;
     long max_segments;
-    struct stat st;
 
-    if (fstat(fd, &st)) {
-        ret = -errno;
-        goto out;
-    }
-
-    if (S_ISCHR(st.st_mode)) {
+    if (S_ISCHR(st->st_mode)) {
         if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
             return ret;
         }
         return -ENOTSUP;
     }
 
-    if (!S_ISBLK(st.st_mode)) {
+    if (!S_ISBLK(st->st_mode)) {
         return -ENOTSUP;
     }
 
     sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
-                                major(st.st_rdev), minor(st.st_rdev));
+                                major(st->st_rdev), minor(st->st_rdev));
     sysfd = open(sysfspath, O_RDONLY);
     if (sysfd == -1) {
         ret = -errno;
@@ -1227,23 +1226,33 @@ out:
 static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
 {
     BDRVRawState *s = bs->opaque;
-
-    if (bs->sg) {
-        int ret = sg_get_max_transfer_length(s->fd);
-
-        if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
-            bs->bl.max_hw_transfer = pow2floor(ret);
-        }
-
-        ret = sg_get_max_segments(s->fd);
-        if (ret > 0) {
-            bs->bl.max_iov = ret;
-        }
-    }
+    struct stat st;
 
     raw_probe_alignment(bs, s->fd, errp);
     bs->bl.min_mem_alignment = s->buf_align;
     bs->bl.opt_mem_alignment = MAX(s->buf_align, qemu_real_host_page_size);
+
+    /*
+     * Maximum transfers are best effort, so it is okay to ignore any
+     * errors.  That said, based on the man page errors in fstat would be
+     * very much unexpected; the only possible case seems to be ENOMEM.
+     */
+    if (fstat(s->fd, &st)) {
+        return;
+    }
+
+    if (bs->sg || S_ISBLK(st.st_mode)) {
+        int ret = hdev_get_max_hw_transfer(s->fd, &st);
+
+        if (ret > 0 && ret <= BDRV_REQUEST_MAX_BYTES) {
+            bs->bl.max_hw_transfer = ret;
+        }
+
+        ret = hdev_get_max_segments(s->fd, &st);
+        if (ret > 0) {
+            bs->bl.max_iov = ret;
+        }
+    }
 }
 
 static int check_for_dasd(int fd)
-- 
2.31.1




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

* [PATCH 07/11] block: feature detection for host block support
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (5 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 06/11] file-posix: try BLKSECTGET on block devices too, do not round to power of 2 Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  8:20   ` Max Reitz
  2021-06-24 18:04 ` [PATCH 08/11] block: check for sys/disk.h Paolo Bonzini
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, Joelle van Dyne, qemu-block, mlevitsk

From: Joelle van Dyne <j@getutm.app>

On Darwin (iOS), there are no system level APIs for directly accessing
host block devices. We detect this at configure time.

Signed-off-by: Joelle van Dyne <j@getutm.app>
Message-Id: <20210315180341.31638-2-j@getutm.app>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/file-posix.c   | 33 ++++++++++++++++++++++-----------
 meson.build          |  6 +++++-
 qapi/block-core.json | 14 ++++++++++----
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index ea102483b0..e56bb491a1 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -42,6 +42,8 @@
 #include "scsi/constants.h"
 
 #if defined(__APPLE__) && (__MACH__)
+#include <sys/ioctl.h>
+#if defined(HAVE_HOST_BLOCK_DEVICE)
 #include <paths.h>
 #include <sys/param.h>
 #include <IOKit/IOKitLib.h>
@@ -52,6 +54,7 @@
 //#include <IOKit/storage/IOCDTypes.h>
 #include <IOKit/storage/IODVDMedia.h>
 #include <CoreFoundation/CoreFoundation.h>
+#endif /* defined(HAVE_HOST_BLOCK_DEVICE) */
 #endif
 
 #ifdef __sun__
@@ -178,7 +181,17 @@ typedef struct BDRVRawReopenState {
     bool check_cache_dropped;
 } BDRVRawReopenState;
 
-static int fd_open(BlockDriverState *bs);
+static int fd_open(BlockDriverState *bs)
+{
+    BDRVRawState *s = bs->opaque;
+
+    /* this is just to ensure s->fd is sane (its called by io ops) */
+    if (s->fd >= 0) {
+        return 0;
+    }
+    return -EIO;
+}
+
 static int64_t raw_getlength(BlockDriverState *bs);
 
 typedef struct RawPosixAIOData {
@@ -3033,6 +3046,7 @@ static BlockStatsSpecific *raw_get_specific_stats(BlockDriverState *bs)
     return stats;
 }
 
+#if defined(HAVE_HOST_BLOCK_DEVICE)
 static BlockStatsSpecific *hdev_get_specific_stats(BlockDriverState *bs)
 {
     BlockStatsSpecific *stats = g_new(BlockStatsSpecific, 1);
@@ -3042,6 +3056,7 @@ static BlockStatsSpecific *hdev_get_specific_stats(BlockDriverState *bs)
 
     return stats;
 }
+#endif /* HAVE_HOST_BLOCK_DEVICE */
 
 static QemuOptsList raw_create_opts = {
     .name = "raw-create-opts",
@@ -3257,6 +3272,8 @@ BlockDriver bdrv_file = {
 /***********************************************/
 /* host device */
 
+#if defined(HAVE_HOST_BLOCK_DEVICE)
+
 #if defined(__APPLE__) && defined(__MACH__)
 static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
                                 CFIndex maxPathSize, int flags);
@@ -3549,16 +3566,6 @@ hdev_co_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
 }
 #endif /* linux */
 
-static int fd_open(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-
-    /* this is just to ensure s->fd is sane (its called by io ops) */
-    if (s->fd >= 0)
-        return 0;
-    return -EIO;
-}
-
 static coroutine_fn int
 hdev_co_pdiscard(BlockDriverState *bs, int64_t offset, int bytes)
 {
@@ -3882,6 +3889,8 @@ static BlockDriver bdrv_host_cdrom = {
 };
 #endif /* __FreeBSD__ */
 
+#endif /* HAVE_HOST_BLOCK_DEVICE */
+
 static void bdrv_file_init(void)
 {
     /*
@@ -3889,6 +3898,7 @@ static void bdrv_file_init(void)
      * registered last will get probed first.
      */
     bdrv_register(&bdrv_file);
+#if defined(HAVE_HOST_BLOCK_DEVICE)
     bdrv_register(&bdrv_host_device);
 #ifdef __linux__
     bdrv_register(&bdrv_host_cdrom);
@@ -3896,6 +3906,7 @@ static void bdrv_file_init(void)
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     bdrv_register(&bdrv_host_cdrom);
 #endif
+#endif /* HAVE_HOST_BLOCK_DEVICE */
 }
 
 block_init(bdrv_file_init);
diff --git a/meson.build b/meson.build
index 62de7ac106..bb3a5be796 100644
--- a/meson.build
+++ b/meson.build
@@ -183,7 +183,7 @@ if targetos == 'windows'
                                       include_directories: include_directories('.'))
 elif targetos == 'darwin'
   coref = dependency('appleframeworks', modules: 'CoreFoundation')
-  iokit = dependency('appleframeworks', modules: 'IOKit')
+  iokit = dependency('appleframeworks', modules: 'IOKit', required: false)
 elif targetos == 'sunos'
   socket = [cc.find_library('socket'),
             cc.find_library('nsl'),
@@ -1147,6 +1147,9 @@ if get_option('cfi')
   add_global_link_arguments(cfi_flags, native: false, language: ['c', 'cpp', 'objc'])
 endif
 
+have_host_block_device = (targetos != 'darwin' or
+    cc.has_header('IOKit/storage/IOMedia.h'))
+
 #################
 # config-host.h #
 #################
@@ -1246,6 +1249,7 @@ config_host_data.set('HAVE_PTY_H', cc.has_header('pty.h'))
 config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
+config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
 
 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
 
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 2ea294129e..a54f37dbef 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -897,7 +897,8 @@
   'discriminator': 'driver',
   'data': {
       'file': 'BlockStatsSpecificFile',
-      'host_device': 'BlockStatsSpecificFile',
+      'host_device': { 'type': 'BlockStatsSpecificFile',
+                       'if': 'defined(HAVE_HOST_BLOCK_DEVICE)' },
       'nvme': 'BlockStatsSpecificNvme' } }
 
 ##
@@ -2814,7 +2815,10 @@
 { 'enum': 'BlockdevDriver',
   'data': [ 'blkdebug', 'blklogwrites', 'blkreplay', 'blkverify', 'bochs',
             'cloop', 'compress', 'copy-on-read', 'dmg', 'file', 'ftp', 'ftps',
-            'gluster', 'host_cdrom', 'host_device', 'http', 'https', 'iscsi',
+            'gluster',
+            {'name': 'host_cdrom', 'if': 'defined(HAVE_HOST_BLOCK_DEVICE)' },
+            {'name': 'host_device', 'if': 'defined(HAVE_HOST_BLOCK_DEVICE)' },
+            'http', 'https', 'iscsi',
             'luks', 'nbd', 'nfs', 'null-aio', 'null-co', 'nvme', 'parallels',
             'preallocate', 'qcow', 'qcow2', 'qed', 'quorum', 'raw', 'rbd',
             { 'name': 'replication', 'if': 'defined(CONFIG_REPLICATION)' },
@@ -3995,8 +3999,10 @@
       'ftp':        'BlockdevOptionsCurlFtp',
       'ftps':       'BlockdevOptionsCurlFtps',
       'gluster':    'BlockdevOptionsGluster',
-      'host_cdrom': 'BlockdevOptionsFile',
-      'host_device':'BlockdevOptionsFile',
+      'host_cdrom':  { 'type': 'BlockdevOptionsFile',
+                       'if': 'defined(HAVE_HOST_BLOCK_DEVICE)' },
+      'host_device': { 'type': 'BlockdevOptionsFile',
+                       'if': 'defined(HAVE_HOST_BLOCK_DEVICE)' },
       'http':       'BlockdevOptionsCurlHttp',
       'https':      'BlockdevOptionsCurlHttps',
       'iscsi':      'BlockdevOptionsIscsi',
-- 
2.31.1




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

* [PATCH 08/11] block: check for sys/disk.h
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (6 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 07/11] block: feature detection for host block support Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-24 18:04 ` [PATCH 09/11] block: try BSD disk size ioctls one after another Paolo Bonzini
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel
  Cc: Peter Maydell, qemu-block, mreitz, Joelle van Dyne, mlevitsk,
	Philippe Mathieu-Daudé

From: Joelle van Dyne <j@getutm.app>

Some BSD platforms do not have this header.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Signed-off-by: Joelle van Dyne <j@getutm.app>
Message-Id: <20210315180341.31638-3-j@getutm.app>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block.c     | 2 +-
 meson.build | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/block.c b/block.c
index 3f456892d0..1d37f133a8 100644
--- a/block.c
+++ b/block.c
@@ -54,7 +54,7 @@
 #ifdef CONFIG_BSD
 #include <sys/ioctl.h>
 #include <sys/queue.h>
-#ifndef __DragonFly__
+#if defined(HAVE_SYS_DISK_H)
 #include <sys/disk.h>
 #endif
 #endif
diff --git a/meson.build b/meson.build
index bb3a5be796..a95a9fbcbf 100644
--- a/meson.build
+++ b/meson.build
@@ -1250,6 +1250,7 @@ config_host_data.set('HAVE_SYS_IOCCOM_H', cc.has_header('sys/ioccom.h'))
 config_host_data.set('HAVE_SYS_KCOV_H', cc.has_header('sys/kcov.h'))
 config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include <stdlib.h>'))
 config_host_data.set('HAVE_HOST_BLOCK_DEVICE', have_host_block_device)
+config_host_data.set('HAVE_SYS_DISK_H', cc.has_header('sys/disk.h'))
 
 config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
 
-- 
2.31.1




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

* [PATCH 09/11] block: try BSD disk size ioctls one after another
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (7 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 08/11] block: check for sys/disk.h Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  8:29   ` Max Reitz
  2021-06-24 18:04 ` [PATCH 10/11] block: detect DKIOCGETBLOCKCOUNT/SIZE before use Paolo Bonzini
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, qemu-block, mlevitsk

Try all the possible ioctls for disk size as long as they are
supported, to keep the #if ladder simple.

Extracted and cleaned up from a patch by Joelle van Dyne and
Warner Losh.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/file-posix.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index e56bb491a1..f16d987c07 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2327,39 +2327,37 @@ static int64_t raw_getlength(BlockDriverState *bs)
 again:
 #endif
     if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
+        size = 0;
 #ifdef DIOCGMEDIASIZE
-        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
-#elif defined(DIOCGPART)
-        {
-                struct partinfo pi;
-                if (ioctl(fd, DIOCGPART, &pi) == 0)
-                        size = pi.media_size;
-                else
-                        size = 0;
+        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) {
+            size = 0;
+        }
+#endif
+#ifdef DIOCGPART
+        if (size == 0) {
+            struct partinfo pi;
+            if (ioctl(fd, DIOCGPART, &pi) == 0) {
+                size = pi.media_size;
+            }
         }
-        if (size == 0)
 #endif
 #if defined(__APPLE__) && defined(__MACH__)
-        {
+        if (size == 0) {
             uint64_t sectors = 0;
             uint32_t sector_size = 0;
 
             if (ioctl(fd, DKIOCGETBLOCKCOUNT, &sectors) == 0
                && ioctl(fd, DKIOCGETBLOCKSIZE, &sector_size) == 0) {
                 size = sectors * sector_size;
-            } else {
-                size = lseek(fd, 0LL, SEEK_END);
-                if (size < 0) {
-                    return -errno;
-                }
             }
         }
-#else
-        size = lseek(fd, 0LL, SEEK_END);
+#endif
+        if (size == 0) {
+            size = lseek(fd, 0LL, SEEK_END);
+        }
         if (size < 0) {
             return -errno;
         }
-#endif
 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
         switch(s->type) {
         case FTYPE_CD:
-- 
2.31.1




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

* [PATCH 10/11] block: detect DKIOCGETBLOCKCOUNT/SIZE before use
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (8 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 09/11] block: try BSD disk size ioctls one after another Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  8:30   ` Max Reitz
  2021-06-24 18:04 ` [PATCH 11/11] file-posix: handle EINTR during ioctl Paolo Bonzini
  2021-06-25  8:37 ` [PATCH v5 00/11] block: file-posix queue Max Reitz
  11 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Warner Losh, mreitz, Joelle van Dyne, qemu-block, mlevitsk

From: Joelle van Dyne <j@getutm.app>

iOS hosts do not have these defined so we fallback to the
default behaviour.

Co-authored-by: Warner Losh <imp@bsdimp.com>
Signed-off-by: Joelle van Dyne <j@getutm.app>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/file-posix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index f16d987c07..74b8216077 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -2341,7 +2341,7 @@ again:
             }
         }
 #endif
-#if defined(__APPLE__) && defined(__MACH__)
+#if defined(DKIOCGETBLOCKCOUNT) && defined(DKIOCGETBLOCKSIZE)
         if (size == 0) {
             uint64_t sectors = 0;
             uint32_t sector_size = 0;
-- 
2.31.1




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

* [PATCH 11/11] file-posix: handle EINTR during ioctl
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (9 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 10/11] block: detect DKIOCGETBLOCKCOUNT/SIZE before use Paolo Bonzini
@ 2021-06-24 18:04 ` Paolo Bonzini
  2021-06-25  8:30   ` Philippe Mathieu-Daudé
  2021-06-25  8:35   ` Max Reitz
  2021-06-25  8:37 ` [PATCH v5 00/11] block: file-posix queue Max Reitz
  11 siblings, 2 replies; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-24 18:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: mreitz, Gordon Watson, qemu-block, mlevitsk

Similar to other handle_aiocb_* functions, handle_aiocb_ioctl needs to cater
for the possibility that ioctl is interrupted by a signal.  Otherwise, the
I/O is incorrectly reported as a failure to the guest.

Reported-by: Gordon Watson <gwatson@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 block/file-posix.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 74b8216077..a26eab0ac3 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1347,7 +1347,9 @@ static int handle_aiocb_ioctl(void *opaque)
     RawPosixAIOData *aiocb = opaque;
     int ret;
 
-    ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf);
+    do {
+        ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf);
+    } while (ret == -1 && errno == EINTR);
     if (ret == -1) {
         return -errno;
     }
-- 
2.31.1



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

* Re: [PATCH 03/11] osdep: provide ROUND_DOWN macro
  2021-06-24 18:04 ` [PATCH 03/11] osdep: provide ROUND_DOWN macro Paolo Bonzini
@ 2021-06-25  7:42   ` Max Reitz
  2021-06-25  8:26   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  7:42 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> osdep.h provides a ROUND_UP macro to hide bitwise operations for the
> purpose of rounding a number up to a power of two; add a ROUND_DOWN
> macro that does the same with truncation towards zero.
>
> While at it, change the formatting of some comments.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   include/qemu/osdep.h | 28 ++++++++++++++++++++++------
>   1 file changed, 22 insertions(+), 6 deletions(-)

What a nice thing to have.

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 04/11] block-backend: align max_transfer to request alignment
  2021-06-24 18:04 ` [PATCH 04/11] block-backend: align max_transfer to request alignment Paolo Bonzini
@ 2021-06-25  7:52   ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  7:52 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> Block device requests must be aligned to bs->bl.request_alignment.
> It makes sense for drivers to align bs->bl.max_transfer the same
> way; however when there is no specified limit, blk_get_max_transfer
> just returns INT_MAX.  Since the contract of the function does not
> specify that INT_MAX means "no maximum", just align the outcome
> of the function (whether INT_MAX or bs->bl.max_transfer) before
> returning it.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/block-backend.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 05/11] block: add max_hw_transfer to BlockLimits
  2021-06-24 18:04 ` [PATCH 05/11] block: add max_hw_transfer to BlockLimits Paolo Bonzini
@ 2021-06-25  7:58   ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  7:58 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> For block host devices, I/O can happen through either the kernel file
> descriptor I/O system calls (preadv/pwritev, io_submit, io_uring)
> or the SCSI passthrough ioctl SG_IO.
>
> In the latter case, the size of each transfer can be limited by the
> HBA, while for file descriptor I/O the kernel is able to split and
> merge I/O in smaller pieces as needed.  Applying the HBA limits to
> file descriptor I/O results in more system calls and suboptimal
> performance, so this patch splits the max_transfer limit in two:
> max_transfer remains valid and is used in general, while max_hw_transfer
> is limited to the maximum hardware size.  max_hw_transfer can then be
> included by the scsi-generic driver in the block limits page, to ensure
> that the stricter hardware limit is used.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/block-backend.c          | 13 +++++++++++++
>   block/file-posix.c             |  2 +-
>   block/io.c                     |  2 ++
>   hw/scsi/scsi-generic.c         |  2 +-
>   include/block/block_int.h      |  7 +++++++
>   include/sysemu/block-backend.h |  1 +
>   6 files changed, 25 insertions(+), 2 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 06/11] file-posix: try BLKSECTGET on block devices too, do not round to power of 2
  2021-06-24 18:04 ` [PATCH 06/11] file-posix: try BLKSECTGET on block devices too, do not round to power of 2 Paolo Bonzini
@ 2021-06-25  8:19   ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  8:19 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> bs->sg is only true for character devices, but block devices can also
> be used with scsi-block and scsi-generic.  Unfortunately BLKSECTGET
> returns bytes in an int for /dev/sgN devices, and sectors in a short
> for block devices, so account for that in the code.
>
> The maximum transfer also need not be a power of 2 (for example I have
> seen disks with 1280 KiB maximum transfer) so there's no need to pass
> the result through pow2floor.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/file-posix.c | 67 ++++++++++++++++++++++++++--------------------
>   1 file changed, 38 insertions(+), 29 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 07/11] block: feature detection for host block support
  2021-06-24 18:04 ` [PATCH 07/11] block: feature detection for host block support Paolo Bonzini
@ 2021-06-25  8:20   ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  8:20 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: Joelle van Dyne, qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> From: Joelle van Dyne <j@getutm.app>
>
> On Darwin (iOS), there are no system level APIs for directly accessing
> host block devices. We detect this at configure time.
>
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> Message-Id: <20210315180341.31638-2-j@getutm.app>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/file-posix.c   | 33 ++++++++++++++++++++++-----------
>   meson.build          |  6 +++++-
>   qapi/block-core.json | 14 ++++++++++----
>   3 files changed, 37 insertions(+), 16 deletions(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 03/11] osdep: provide ROUND_DOWN macro
  2021-06-24 18:04 ` [PATCH 03/11] osdep: provide ROUND_DOWN macro Paolo Bonzini
  2021-06-25  7:42   ` Max Reitz
@ 2021-06-25  8:26   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 25+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-25  8:26 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: mlevitsk, qemu-block, mreitz

On 6/24/21 8:04 PM, Paolo Bonzini wrote:
> osdep.h provides a ROUND_UP macro to hide bitwise operations for the
> purpose of rounding a number up to a power of two; add a ROUND_DOWN
> macro that does the same with truncation towards zero.
> 
> While at it, change the formatting of some comments.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/osdep.h | 28 ++++++++++++++++++++++------
>  1 file changed, 22 insertions(+), 6 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>



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

* Re: [PATCH 09/11] block: try BSD disk size ioctls one after another
  2021-06-24 18:04 ` [PATCH 09/11] block: try BSD disk size ioctls one after another Paolo Bonzini
@ 2021-06-25  8:29   ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  8:29 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> Try all the possible ioctls for disk size as long as they are
> supported, to keep the #if ladder simple.
>
> Extracted and cleaned up from a patch by Joelle van Dyne and
> Warner Losh.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/file-posix.c | 34 ++++++++++++++++------------------
>   1 file changed, 16 insertions(+), 18 deletions(-)

Thanks, that’s much better.

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 10/11] block: detect DKIOCGETBLOCKCOUNT/SIZE before use
  2021-06-24 18:04 ` [PATCH 10/11] block: detect DKIOCGETBLOCKCOUNT/SIZE before use Paolo Bonzini
@ 2021-06-25  8:30   ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  8:30 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel
  Cc: Warner Losh, Joelle van Dyne, qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> From: Joelle van Dyne <j@getutm.app>
>
> iOS hosts do not have these defined so we fallback to the
> default behaviour.
>
> Co-authored-by: Warner Losh <imp@bsdimp.com>
> Signed-off-by: Joelle van Dyne <j@getutm.app>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/file-posix.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH 11/11] file-posix: handle EINTR during ioctl
  2021-06-24 18:04 ` [PATCH 11/11] file-posix: handle EINTR during ioctl Paolo Bonzini
@ 2021-06-25  8:30   ` Philippe Mathieu-Daudé
  2021-06-25  8:35   ` Max Reitz
  1 sibling, 0 replies; 25+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-25  8:30 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: mlevitsk, qemu-block, Gordon Watson, mreitz

On 6/24/21 8:04 PM, Paolo Bonzini wrote:
> Similar to other handle_aiocb_* functions, handle_aiocb_ioctl needs to cater
> for the possibility that ioctl is interrupted by a signal.  Otherwise, the
> I/O is incorrectly reported as a failure to the guest.
> 
> Reported-by: Gordon Watson <gwatson@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  block/file-posix.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 74b8216077..a26eab0ac3 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1347,7 +1347,9 @@ static int handle_aiocb_ioctl(void *opaque)
>      RawPosixAIOData *aiocb = opaque;
>      int ret;
>  
> -    ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf);
> +    do {
> +        ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf);
> +    } while (ret == -1 && errno == EINTR);

Shouldn't this use the TFR macro instead?

>      if (ret == -1) {
>          return -errno;
>      }
> 



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

* Re: [PATCH 11/11] file-posix: handle EINTR during ioctl
  2021-06-24 18:04 ` [PATCH 11/11] file-posix: handle EINTR during ioctl Paolo Bonzini
  2021-06-25  8:30   ` Philippe Mathieu-Daudé
@ 2021-06-25  8:35   ` Max Reitz
  1 sibling, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  8:35 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel; +Cc: Gordon Watson, qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> Similar to other handle_aiocb_* functions, handle_aiocb_ioctl needs to cater
> for the possibility that ioctl is interrupted by a signal.  Otherwise, the
> I/O is incorrectly reported as a failure to the guest.
>
> Reported-by: Gordon Watson <gwatson@redhat.com>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>   block/file-posix.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 74b8216077..a26eab0ac3 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1347,7 +1347,9 @@ static int handle_aiocb_ioctl(void *opaque)
>       RawPosixAIOData *aiocb = opaque;
>       int ret;
>   
> -    ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf);
> +    do {
> +        ret = ioctl(aiocb->aio_fildes, aiocb->ioctl.cmd, aiocb->ioctl.buf);
> +    } while (ret == -1 && errno == EINTR);
>       if (ret == -1) {
>           return -errno;
>       }

I think the macro TFR() from qemu-common.h could be applied here, 
probably like `TFR(ret = ioctl(...));`.

No matter:

Reviewed-by: Max Reitz <mreitz@redhat.com>



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

* Re: [PATCH v5 00/11] block: file-posix queue
  2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
                   ` (10 preceding siblings ...)
  2021-06-24 18:04 ` [PATCH 11/11] file-posix: handle EINTR during ioctl Paolo Bonzini
@ 2021-06-25  8:37 ` Max Reitz
  2021-06-25  8:52   ` Paolo Bonzini
  11 siblings, 1 reply; 25+ messages in thread
From: Max Reitz @ 2021-06-25  8:37 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel, Kevin Wolf; +Cc: qemu-block, mlevitsk

On 24.06.21 20:04, Paolo Bonzini wrote:
> New patches:
> - 3/4 (for review comments),
> - 9 (split for ease of review),
> - 11 (new bugfix)
>
> v1->v2: add missing patch
>
> v2->v3: add max_hw_transfer to BlockLimits
>
> v3->v4: fix compilation after patch 1, tweak commit messages according
>          to Vladimir's review
>
> v4->v5: round down max_transfer and max_hw_transfer to request alignment
>          checkpatch fixes
>          return -ENOTSUP, -not -EIO if block limits ioctls fail
>          handle host_cdrom like host_device in QAPI
>          split "block: try BSD disk size ioctls one after another"
>          new bugfix patch "file-posix: handle EINTR during ioctl"

Thanks, looks good to me, though I’m afraid I’ll be on PTO the next two 
weeks so I can’t take this series through my tree... (I don’t really 
want to send a pull request today when I probably wouldn’t be able to 
deal with potential problems)

Max



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

* Re: [PATCH v5 00/11] block: file-posix queue
  2021-06-25  8:37 ` [PATCH v5 00/11] block: file-posix queue Max Reitz
@ 2021-06-25  8:52   ` Paolo Bonzini
  2021-06-25  9:28     ` Max Reitz
  0 siblings, 1 reply; 25+ messages in thread
From: Paolo Bonzini @ 2021-06-25  8:52 UTC (permalink / raw)
  To: Max Reitz, qemu-devel, Kevin Wolf; +Cc: qemu-block, mlevitsk

On 25/06/21 10:37, Max Reitz wrote:
> Thanks, looks good to me, though I’m afraid I’ll be on PTO the next two 
> weeks so I can’t take this series through my tree... (I don’t really 
> want to send a pull request today when I probably wouldn’t be able to 
> deal with potential problems)

I can take it too, if it's okay for you.

Paolo



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

* Re: [PATCH v5 00/11] block: file-posix queue
  2021-06-25  8:52   ` Paolo Bonzini
@ 2021-06-25  9:28     ` Max Reitz
  0 siblings, 0 replies; 25+ messages in thread
From: Max Reitz @ 2021-06-25  9:28 UTC (permalink / raw)
  To: Paolo Bonzini, qemu-devel, Kevin Wolf; +Cc: qemu-block, mlevitsk

On 25.06.21 10:52, Paolo Bonzini wrote:
> On 25/06/21 10:37, Max Reitz wrote:
>> Thanks, looks good to me, though I’m afraid I’ll be on PTO the next 
>> two weeks so I can’t take this series through my tree... (I don’t 
>> really want to send a pull request today when I probably wouldn’t be 
>> able to deal with potential problems)
>
> I can take it too, if it's okay for you.

Sure!



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

end of thread, other threads:[~2021-06-25 10:01 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-24 18:04 [PATCH v5 00/11] block: file-posix queue Paolo Bonzini
2021-06-24 18:04 ` [PATCH 01/11] file-posix: fix max_iov for /dev/sg devices Paolo Bonzini
2021-06-24 18:04 ` [PATCH 02/11] scsi-generic: pass max_segments via max_iov field in BlockLimits Paolo Bonzini
2021-06-24 18:04 ` [PATCH 03/11] osdep: provide ROUND_DOWN macro Paolo Bonzini
2021-06-25  7:42   ` Max Reitz
2021-06-25  8:26   ` Philippe Mathieu-Daudé
2021-06-24 18:04 ` [PATCH 04/11] block-backend: align max_transfer to request alignment Paolo Bonzini
2021-06-25  7:52   ` Max Reitz
2021-06-24 18:04 ` [PATCH 05/11] block: add max_hw_transfer to BlockLimits Paolo Bonzini
2021-06-25  7:58   ` Max Reitz
2021-06-24 18:04 ` [PATCH 06/11] file-posix: try BLKSECTGET on block devices too, do not round to power of 2 Paolo Bonzini
2021-06-25  8:19   ` Max Reitz
2021-06-24 18:04 ` [PATCH 07/11] block: feature detection for host block support Paolo Bonzini
2021-06-25  8:20   ` Max Reitz
2021-06-24 18:04 ` [PATCH 08/11] block: check for sys/disk.h Paolo Bonzini
2021-06-24 18:04 ` [PATCH 09/11] block: try BSD disk size ioctls one after another Paolo Bonzini
2021-06-25  8:29   ` Max Reitz
2021-06-24 18:04 ` [PATCH 10/11] block: detect DKIOCGETBLOCKCOUNT/SIZE before use Paolo Bonzini
2021-06-25  8:30   ` Max Reitz
2021-06-24 18:04 ` [PATCH 11/11] file-posix: handle EINTR during ioctl Paolo Bonzini
2021-06-25  8:30   ` Philippe Mathieu-Daudé
2021-06-25  8:35   ` Max Reitz
2021-06-25  8:37 ` [PATCH v5 00/11] block: file-posix queue Max Reitz
2021-06-25  8:52   ` Paolo Bonzini
2021-06-25  9:28     ` Max Reitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).