9ae3a8
From 8406a85d6b78d2f3478a204b5eab0cd714fe9aa4 Mon Sep 17 00:00:00 2001
9ae3a8
From: Markus Armbruster <armbru@redhat.com>
9ae3a8
Date: Fri, 31 Oct 2014 16:29:53 +0100
9ae3a8
Subject: [PATCH 16/19] virtio-blk: Bypass error action and I/O accounting on
9ae3a8
 invalid r/w
9ae3a8
9ae3a8
Message-id: <1414772996-17272-3-git-send-email-armbru@redhat.com>
9ae3a8
Patchwork-id: 62014
9ae3a8
O-Subject: [PATCH RHEL-7.1 qemu-kvm 2/5] virtio-blk: Bypass error action and I/O accounting on invalid r/w
9ae3a8
Bugzilla: 1085232
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
9ae3a8
When a device model's I/O operation fails, we execute the error
9ae3a8
action.  This lets layers above QEMU implement thin provisioning, or
9ae3a8
attempt to correct errors before they reach the guest.  But when the
9ae3a8
I/O operation fails because it's invalid, reporting the error to the
9ae3a8
guest is the only sensible action.
9ae3a8
9ae3a8
If the guest's read or write asks for an invalid sector range, fail
9ae3a8
the request right away, without considering the error action.  No
9ae3a8
change with error action BDRV_ACTION_REPORT.
9ae3a8
9ae3a8
Furthermore, bypass I/O accounting, because we want to track only I/O
9ae3a8
that actually reaches the block layer.
9ae3a8
9ae3a8
The next commit will extend "invalid sector range" to cover attempts
9ae3a8
to read/write beyond the end of the medium.
9ae3a8
9ae3a8
Signed-off-by: Markus Armbruster <armbru@redhat.com>
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
(cherry picked from commit 42e38c1fd0199155d32f3464aedce282d3d7f6a1)
9ae3a8
9ae3a8
Straightforward semantic conflict: requests still have to be freed
9ae3a8
with g_free() because we don't have commit 671ec3f.
9ae3a8
9ae3a8
Signed-off-by: Markus Armbruster <armbru@redhat.com>
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 hw/block/virtio-blk.c | 14 ++++++++------
9ae3a8
 1 file changed, 8 insertions(+), 6 deletions(-)
9ae3a8
9ae3a8
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
9ae3a8
index 0f1d3ec..ffb311c 100644
9ae3a8
--- a/hw/block/virtio-blk.c
9ae3a8
+++ b/hw/block/virtio-blk.c
9ae3a8
@@ -300,15 +300,16 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb)
9ae3a8
 
9ae3a8
     sector = ldq_p(&req->out->sector);
9ae3a8
 
9ae3a8
-    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
9ae3a8
-
9ae3a8
     trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512);
9ae3a8
 
9ae3a8
     if (!virtio_blk_sect_range_ok(req->dev, sector, req->qiov.size)) {
9ae3a8
-        virtio_blk_rw_complete(req, -EIO);
9ae3a8
+        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
9ae3a8
+        g_free(req);
9ae3a8
         return;
9ae3a8
     }
9ae3a8
 
9ae3a8
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_WRITE);
9ae3a8
+
9ae3a8
     if (mrb->num_writes == 32) {
9ae3a8
         virtio_submit_multiwrite(req->dev->bs, mrb);
9ae3a8
     }
9ae3a8
@@ -330,14 +331,15 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
9ae3a8
 
9ae3a8
     sector = ldq_p(&req->out->sector);
9ae3a8
 
9ae3a8
-    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
9ae3a8
-
9ae3a8
     trace_virtio_blk_handle_read(req, sector, req->qiov.size / 512);
9ae3a8
 
9ae3a8
     if (!virtio_blk_sect_range_ok(req->dev, sector, req->qiov.size)) {
9ae3a8
-        virtio_blk_rw_complete(req, -EIO);
9ae3a8
+        virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
9ae3a8
+        g_free(req);
9ae3a8
         return;
9ae3a8
     }
9ae3a8
+
9ae3a8
+    bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ);
9ae3a8
     bdrv_aio_readv(req->dev->bs, sector, &req->qiov,
9ae3a8
                    req->qiov.size / BDRV_SECTOR_SIZE,
9ae3a8
                    virtio_blk_rw_complete, req);
9ae3a8
-- 
9ae3a8
1.8.3.1
9ae3a8