From e5a8c6d615c135fb20b0fd539117fc659533ccb1 Mon Sep 17 00:00:00 2001
From: Markus Armbruster <armbru@redhat.com>
Date: Tue, 22 Jul 2014 09:16:03 -0500
Subject: [CHANGE 14/17] virtio-blk: Bypass error action and I/O accounting on
 invalid r/w
To: rhvirt-patches@redhat.com,
    jen@redhat.com

RH-Author: Markus Armbruster <armbru@redhat.com>
Message-id: <1406020565-25364-10-git-send-email-armbru@redhat.com>
Patchwork-id: 60001
O-Subject: [PATCH 6.6 qemu-kvm v2 09/11] virtio-blk: Bypass error action and I/O accounting on invalid r/w
Bugzilla: 1064643
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
RH-Acked-by: Fam Zheng <famz@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>

When a device model's I/O operation fails, we execute the error
action.  This lets layers above QEMU implement thin provisioning, or
attempt to correct errors before they reach the guest.  But when the
I/O operation fails because it's invalid, reporting the error to the
guest is the only sensible action.

If the guest's read or write asks for an invalid sector range, fail
the request right away, without considering the error action.  No
change with error action BDRV_ACTION_REPORT.

Furthermore, bypass I/O accounting, because we want to track only I/O
that actually reaches the block layer.

The next commit will extend "invalid sector range" to cover attempts
to read/write beyond the end of the medium.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 42e38c1fd0199155d32f3464aedce282d3d7f6a1)
Signed-off-by: jen <jen@redhat.com>

Conflicts:
	hw/block/virtio-blk.c

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hw/virtio-blk.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

Signed-off-by: jen <jen@redhat.com>
---
 hw/virtio-blk.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index a5f5d93..1909a90 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -329,13 +329,14 @@ static void virtio_blk_handle_write(BlockRequest *blkreq, int *num_writes,
 {
     trace_virtio_blk_handle_write(req, req->out->sector, req->qiov.size / 512);
 
+    if (!virtio_blk_sect_range_ok(req->dev, req->out->sector, req->qiov.size)) {
+        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        qemu_free(req);
+        return;
+    }
+
     bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
 
-    if (!virtio_blk_sect_range_ok(req->dev, req->out->sector, req->qiov.size)) {
-        virtio_blk_rw_complete(req, -EIO);
-        return;
-    }
-
     if (req->dev->bs != *old_bs || *num_writes == 32) {
         if (*old_bs != NULL) {
             do_multiwrite(*old_bs, blkreq, *num_writes);
@@ -358,13 +359,14 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
 {
     BlockDriverAIOCB *acb;
 
+    if (!virtio_blk_sect_range_ok(req->dev, req->out->sector, req->qiov.size)) {
+        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
+        qemu_free(req);
+        return;
+    }
+
     bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
 
-    if (!virtio_blk_sect_range_ok(req->dev, req->out->sector, req->qiov.size)) {
-        virtio_blk_rw_complete(req, -EIO);
-        return;
-    }
-
     acb = bdrv_aio_readv(req->dev->bs, req->out->sector, &req->qiov,
                          req->qiov.size / 512, virtio_blk_rw_complete, req);
     if (!acb) {
-- 
1.9.3

