[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/37] scsi-disk: handle io_canceled uniformly and c
From: |
Michael Roth |
Subject: |
[Qemu-devel] [PATCH 11/37] scsi-disk: handle io_canceled uniformly and correctly |
Date: |
Tue, 2 Apr 2013 16:45:16 -0500 |
From: Paolo Bonzini <address@hidden>
Always check it immediately after calling bdrv_acct_done, and
always do a "goto done" in case the "done" label has to free
some memory---as is the case for scsi_unmap_complete in the
previous patch.
This patch could fix problems that happen when a request is
split into multiple parts, and one of them is canceled. Then
the next part is fired, but the HBA's cancellation callbacks have
fired already. Whether this happens or not, depends on how the
block/ driver implements AIO cancellation. It it does a simple
bdrv_drain_all() or similar, then it will not have a problem.
If it only cancels the given AIOCB, this scenario could happen.
Cc: address@hidden
Signed-off-by: Paolo Bonzini <address@hidden>
(cherry picked from commit 0c92e0e6b64c9061f7365a2712b9055ea35b52f9)
Signed-off-by: Michael Roth <address@hidden>
---
hw/scsi-disk.c | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 28e75bb..6bc739d 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -176,6 +176,9 @@ static void scsi_aio_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -221,6 +224,10 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+ if (r->req.io_canceled) {
+ goto done;
+ }
+
if (scsi_is_cmd_fua(&r->req.cmd)) {
bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH);
r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_aio_complete, r);
@@ -228,6 +235,8 @@ static void scsi_write_do_fua(SCSIDiskReq *r)
}
scsi_req_complete(&r->req, GOOD);
+
+done:
if (!r->req.io_canceled) {
scsi_req_unref(&r->req);
}
@@ -241,6 +250,9 @@ static void scsi_dma_complete(void *opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -272,6 +284,9 @@ static void scsi_read_complete(void * opaque, int ret)
assert(r->req.aiocb != NULL);
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -303,6 +318,9 @@ static void scsi_do_read(void *opaque, int ret)
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
}
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
@@ -310,10 +328,6 @@ static void scsi_do_read(void *opaque, int ret)
}
}
- if (r->req.io_canceled) {
- return;
- }
-
/* The request is used as the AIO opaque value, so add a ref. */
scsi_req_ref(&r->req);
@@ -421,6 +435,9 @@ static void scsi_write_complete(void * opaque, int ret)
r->req.aiocb = NULL;
bdrv_acct_done(s->qdev.conf.bs, &r->acct);
}
+ if (r->req.io_canceled) {
+ goto done;
+ }
if (ret < 0) {
if (scsi_handle_rw_error(r, -ret)) {
--
1.7.9.5
- [Qemu-devel] [PATCH 01/37] target-ppc: Fix "G2leGP3" PVR, (continued)
- [Qemu-devel] [PATCH 01/37] target-ppc: Fix "G2leGP3" PVR, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 02/37] coroutine: trim down nesting level in perf_nesting test, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 03/37] block: complete all IOs before .bdrv_truncate, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 04/37] tap: forbid creating multiqueue tap when hub is used, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 05/37] qemu-char.c: fix waiting for telnet connection message, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 06/37] net: reduce the unnecessary memory allocation of multiqueue, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 08/37] vga: fix byteswapping., Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 09/37] qmp: netdev_add is like -netdev, not -net, fix documentation, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 07/37] help: add docs for multiqueue tap options, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 10/37] qemu-ga: make guest-sync-delimited available during fsfreeze, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 11/37] scsi-disk: handle io_canceled uniformly and correctly,
Michael Roth <=
- [Qemu-devel] [PATCH 12/37] iscsi: look for pkg-config file too, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 13/37] scsi: do not call scsi_read_data/scsi_write_data for a canceled request, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 14/37] scsi-disk: do not complete canceled UNMAP requests, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 15/37] rtc-test: Fix test failures with recent glib, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 16/37] Allow virtio-net features for legacy s390 virtio bus, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 17/37] pseries: Add compatible property to root of device tree, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 18/37] qcow2: make is_allocated return true for zero clusters, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 19/37] qemu-ga: use key-value store to avoid recycling fd handles after restart, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 21/37] tcg: Fix occasional TCG broken problem when ldst optimization enabled, Michael Roth, 2013/04/02
- [Qemu-devel] [PATCH 22/37] virtio-ccw: Queue sanity check for notify hypercall., Michael Roth, 2013/04/02