From 8e6c01e698283111e609498daf53915b5fad6563 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Feb 2012 14:11:47 +0100 Subject: [PATCH 031/109] scsi-disk: reconcile differences around cancellation RH-Author: Paolo Bonzini Message-id: <1329919979-20948-31-git-send-email-pbonzini@redhat.com> Patchwork-id: 37509 O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 030/102] scsi-disk: reconcile differences around cancellation Bugzilla: 782029 RH-Acked-by: Laszlo Ersek RH-Acked-by: Orit Wasserman RH-Acked-by: Gerd Hoffmann Upstream commit c7bae6a (scsi-disk: bump SCSIRequest reference count until aio completion runs, 2011-10-25) is a bit different from what went into RHEL6.2. Now that the previous patch introduced io_canceled, pull the differences. --- hw/scsi-disk.c | 24 +++++++++++++----------- 1 files changed, 13 insertions(+), 11 deletions(-) Signed-off-by: Michal Novotny --- hw/scsi-disk.c | 24 +++++++++++++----------- 1 files changed, 13 insertions(+), 11 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 2cc61d7..7f30567 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -101,16 +101,16 @@ static void scsi_cancel_io(SCSIRequest *req) SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); DPRINTF("Cancel tag=0x%x\n", req->tag); + r->status &= ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK); if (r->req.aiocb) { bdrv_aio_cancel(r->req.aiocb); - } - r->req.aiocb = NULL; - if (r->status & SCSI_REQ_STATUS_RETRY) { - r->status &= ~(SCSI_REQ_STATUS_RETRY | SCSI_REQ_STATUS_RETRY_TYPE_MASK); - /* This reference was left in by scsi_handle_rw_error. */ + /* This reference was left in by scsi_*_data. We take ownership of + * it the moment scsi_req_cancel is called, independent of whether + * bdrv_aio_cancel completes the request or not. */ scsi_req_unref(&r->req); } + r->req.aiocb = NULL; } static void scsi_read_complete(void * opaque, int ret) @@ -138,10 +138,11 @@ static void scsi_read_complete(void * opaque, int ret) scsi_req_data(&r->req, r->iov.iov_len); done: - scsi_req_unref(&r->req); + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); + } } - /* Read more data from scsi device into buffer. */ static void scsi_read_data(SCSIRequest *req) { @@ -165,7 +166,7 @@ static void scsi_read_data(SCSIRequest *req) /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); - /* Save a ref for scsi_read_complete, in case r is canceled. */ + /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { DPRINTF("Data transfer direction invalid\n"); @@ -274,7 +275,9 @@ static void scsi_write_complete(void * opaque, int ret) } done: - scsi_req_unref(&r->req); + if (!r->req.io_canceled) { + scsi_req_unref(&r->req); + } } static void scsi_write_data(SCSIRequest *req) @@ -286,7 +289,7 @@ static void scsi_write_data(SCSIRequest *req) /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); - /* Save a ref for scsi_write_complete, in case r is canceled. */ + /* The request is used as the AIO opaque value, so add a ref. */ scsi_req_ref(&r->req); if (r->req.cmd.mode != SCSI_XFER_TO_DEV) { DPRINTF("Data transfer direction invalid\n"); @@ -345,7 +348,6 @@ static void scsi_dma_restart_bh(void *opaque) scsi_req_complete(&r->req, GOOD); } } - /* This reference was left in by scsi_handle_rw_error. */ scsi_req_unref(&r->req); } } -- 1.7.7.6