All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] xen_disk: convert discard input to byte ranges
@ 2016-11-18 10:24 ` Olaf Hering
  0 siblings, 0 replies; 32+ messages in thread
From: Olaf Hering @ 2016-11-18 10:24 UTC (permalink / raw)
  To: qemu-block
  Cc: Olaf Hering, Stefano Stabellini, Anthony Perard, Kevin Wolf,
	Max Reitz, open list:X86, open list:All patches CC here

The guest sends discard requests as u64 sector/count pairs, but the
block layer operates internally with s64/s32 pairs. The conversion
leads to IO errors in the guest, the discard request is not processed.

  domU.cfg:
  'vdev=xvda, format=qcow2, backendtype=qdisk, target=/x.qcow2'
  domU:
  mkfs.ext4 -F /dev/xvda
  Discarding device blocks: failed - Input/output error

Fix this by splitting the request into chunks of BDRV_REQUEST_MAX_SECTORS.
Add input range checking to avoid overflow.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 hw/block/xen_disk.c | 45 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 3a7dc19..c3f572f 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -660,6 +660,41 @@ static void qemu_aio_complete(void *opaque, int ret)
     qemu_bh_schedule(ioreq->blkdev->bh);
 }
 
+static bool blk_split_discard(struct ioreq *ioreq, blkif_sector_t sector_number,
+                              uint64_t nr_sectors)
+{
+    struct XenBlkDev *blkdev = ioreq->blkdev;
+    int64_t byte_offset;
+    int byte_chunk;
+    uint64_t sec_start = sector_number;
+    uint64_t sec_count = nr_sectors;
+    uint64_t byte_remaining;
+    uint64_t limit = BDRV_REQUEST_MAX_SECTORS << BDRV_SECTOR_BITS;
+
+    /* Wrap around? */
+    if ((sec_start + sec_count) < sec_count) {
+        return false;
+    }
+    /* Overflowing byte limit? */
+    if ((sec_start + sec_count) > ((INT64_MAX + INT_MAX) >> BDRV_SECTOR_BITS)) {
+        return false;
+    }
+
+    byte_offset = sec_start << BDRV_SECTOR_BITS;
+    byte_remaining = sec_count << BDRV_SECTOR_BITS;
+
+    do {
+        byte_chunk = byte_remaining > limit ? limit : byte_remaining;
+        ioreq->aio_inflight++;
+        blk_aio_pdiscard(blkdev->blk, byte_offset, byte_chunk,
+                         qemu_aio_complete, ioreq);
+        byte_remaining -= byte_chunk;
+        byte_offset += byte_chunk;
+    } while (byte_remaining > 0);
+
+    return true;
+}
+
 static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
 {
     struct XenBlkDev *blkdev = ioreq->blkdev;
@@ -708,12 +743,10 @@ static int ioreq_runio_qemu_aio(struct ioreq *ioreq)
         break;
     case BLKIF_OP_DISCARD:
     {
-        struct blkif_request_discard *discard_req = (void *)&ioreq->req;
-        ioreq->aio_inflight++;
-        blk_aio_pdiscard(blkdev->blk,
-                         discard_req->sector_number << BDRV_SECTOR_BITS,
-                         discard_req->nr_sectors << BDRV_SECTOR_BITS,
-                         qemu_aio_complete, ioreq);
+        struct blkif_request_discard *req = (void *)&ioreq->req;
+        if (!blk_split_discard(ioreq, req->sector_number, req->nr_sectors)) {
+            goto err;
+        }
         break;
     }
     default:

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

end of thread, other threads:[~2016-11-23 18:51 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-18 10:24 [Qemu-devel] [PATCH] xen_disk: convert discard input to byte ranges Olaf Hering
2016-11-18 10:24 ` Olaf Hering
2016-11-18 10:30 ` [Qemu-devel] " Olaf Hering
2016-11-18 10:30   ` Olaf Hering
2016-11-23 10:49   ` [Qemu-devel] " Olaf Hering
2016-11-23 10:49     ` Olaf Hering
2016-11-23 11:02     ` [Qemu-devel] " Olaf Hering
2016-11-23 11:02       ` Olaf Hering
2016-11-23 18:51       ` [Qemu-devel] " Stefano Stabellini
2016-11-23 18:51         ` Stefano Stabellini
2016-11-18 13:43 ` [Qemu-devel] " Eric Blake
2016-11-18 13:43   ` Eric Blake
2016-11-18 14:19   ` Olaf Hering
2016-11-18 14:19     ` Olaf Hering
2016-11-18 14:35     ` Eric Blake
2016-11-18 14:35       ` Eric Blake
2016-11-18 15:38       ` Kevin Wolf
2016-11-18 15:38         ` Kevin Wolf
2016-11-18 16:39 ` Eric Blake
2016-11-18 16:39   ` Eric Blake
2016-11-18 17:41   ` Olaf Hering
2016-11-18 17:41     ` Olaf Hering
2016-11-18 18:50     ` Eric Blake
2016-11-18 18:50       ` Eric Blake
2016-11-22 16:12       ` Olaf Hering
2016-11-22 16:12         ` Olaf Hering
2016-11-22 16:32         ` Eric Blake
2016-11-22 16:32           ` Eric Blake
2016-11-22 17:00           ` Olaf Hering
2016-11-22 17:00             ` Olaf Hering
2016-11-22 17:11             ` Eric Blake
2016-11-22 17:11               ` 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.