From d89683388c9981e3cdabcc5dfdfc529a7a105049 Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: Fam Zheng Date: Fri, 24 Apr 2015 08:44:44 -0500 Subject: [CHANGE 24/29] scsi: Introduce scsi_req_cancel_complete To: rhvirt-patches@redhat.com, jen@redhat.com RH-Author: Fam Zheng Message-id: <1429865088-13298-25-git-send-email-famz@redhat.com> Patchwork-id: 64925 O-Subject: [RHEL-6.7 qemu-kvm PATCH v7 24/28] scsi: Introduce scsi_req_cancel_complete Bugzilla: 1069519 RH-Acked-by: Paolo Bonzini RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Max Reitz Let the aio cb do the clean up and notification job after scsi_req_cancel, in preparation for asynchronous cancellation. Signed-off-by: Fam Zheng Signed-off-by: Paolo Bonzini (cherry picked from commit d5776465ee9a55815792efa34d79de240f4ffd99) Signed-off-by: Fam Zheng Signed-off-by: Jeff E. Nelson Conflicts: hw/scsi-disk.c The callbacks are different in downstream: we don't have unmap and write same support, as well as read FUA. --- hw/scsi-bus.c | 14 ++++++++++---- hw/scsi-disk.c | 16 ++++++++++++++++ hw/scsi-generic.c | 1 + hw/scsi.h | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) Signed-off-by: Jeff E. Nelson --- hw/scsi-bus.c | 14 ++++++++++---- hw/scsi-disk.c | 16 ++++++++++++++++ hw/scsi-generic.c | 1 + hw/scsi.h | 1 + 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index aa82df8..c5ae470 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -1476,6 +1476,16 @@ void scsi_req_complete(SCSIRequest *req, int status) scsi_req_unref(req); } +/* Called by the devices when the request is canceled. */ +void scsi_req_cancel_complete(SCSIRequest *req) +{ + assert(req->io_canceled); + if (req->bus->info->cancel) { + req->bus->info->cancel(req); + } + scsi_req_unref(req); +} + void scsi_req_cancel(SCSIRequest *req) { if (!req->enqueued) { @@ -1487,10 +1497,6 @@ void scsi_req_cancel(SCSIRequest *req) if (req->aiocb) { bdrv_aio_cancel(req->aiocb); } - if (req->bus->info->cancel) { - req->bus->info->cancel(req); - } - scsi_req_unref(req); } static int scsi_ua_precedence(SCSISense sense) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 577d45f..3f09d49 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -157,6 +157,10 @@ static void scsi_flush_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) { + scsi_req_cancel_complete(&r->req); + goto done; + } if (ret < 0) { if (scsi_handle_rw_error(r, -ret)) { @@ -218,6 +222,10 @@ 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) { + scsi_req_cancel_complete(&r->req); + goto done; + } if (ret < 0) { if (scsi_handle_rw_error(r, -ret)) { @@ -247,6 +255,10 @@ 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) { + scsi_req_cancel_complete(&r->req); + goto done; + } if (ret < 0) { if (scsi_handle_rw_error(r, -ret)) { @@ -372,6 +384,10 @@ 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) { + scsi_req_cancel_complete(&r->req); + goto done; + } if (ret < 0) { if (scsi_handle_rw_error(r, -ret)) { diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 2752ba6..18f3549 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -96,6 +96,7 @@ static void scsi_command_complete(void *opaque, int ret) r->req.aiocb = NULL; if (r->req.io_canceled) { + scsi_req_cancel_complete(&r->req); goto done; } if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) { diff --git a/hw/scsi.h b/hw/scsi.h index 82135ae..1bfc98b 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -235,6 +235,7 @@ void scsi_req_data(SCSIRequest *req, int len); void scsi_req_complete(SCSIRequest *req, int status); uint8_t *scsi_req_get_buf(SCSIRequest *req); int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len); +void scsi_req_cancel_complete(SCSIRequest *req); void scsi_req_cancel(SCSIRequest *req); void scsi_req_retry(SCSIRequest *req); void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense); -- 2.1.0