qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [6893] Fix DMA API when handling an immediate error from bl


From: Anthony Liguori
Subject: [Qemu-devel] [6893] Fix DMA API when handling an immediate error from block layer ( Avi Kivity)
Date: Sat, 28 Mar 2009 16:11:25 +0000

Revision: 6893
          http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=6893
Author:   aliguori
Date:     2009-03-28 16:11:25 +0000 (Sat, 28 Mar 2009)
Log Message:
-----------
Fix DMA API when handling an immediate error from block layer (Avi Kivity)

The block layer may signal an immediate error on an asynchronous request
by returning NULL.  The DMA API did not handle this correctly, returning
an AIO request which would never complete (and which would crash if
cancelled).

Fix by detecting the failure and propagating it.

Signed-off-by: Avi Kivity <address@hidden>
Signed-off-by: Anthony Liguori <address@hidden>

Modified Paths:
--------------
    trunk/dma-helpers.c

Modified: trunk/dma-helpers.c
===================================================================
--- trunk/dma-helpers.c 2009-03-28 16:11:20 UTC (rev 6892)
+++ trunk/dma-helpers.c 2009-03-28 16:11:25 UTC (rev 6893)
@@ -70,20 +70,26 @@
     qemu_bh_schedule(dbs->bh);
 }
 
-static void dma_bdrv_cb(void *opaque, int ret)
+static void dma_bdrv_unmap(DMAAIOCB *dbs)
 {
-    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
-    target_phys_addr_t cur_addr, cur_len;
-    void *mem;
     int i;
 
-    dbs->acb = NULL;
-    dbs->sector_num += dbs->iov.size / 512;
     for (i = 0; i < dbs->iov.niov; ++i) {
         cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
                                   dbs->iov.iov[i].iov_len, !dbs->is_write,
                                   dbs->iov.iov[i].iov_len);
     }
+}
+
+void dma_bdrv_cb(void *opaque, int ret)
+{
+    DMAAIOCB *dbs = (DMAAIOCB *)opaque;
+    target_phys_addr_t cur_addr, cur_len;
+    void *mem;
+
+    dbs->acb = NULL;
+    dbs->sector_num += dbs->iov.size / 512;
+    dma_bdrv_unmap(dbs);
     qemu_iovec_reset(&dbs->iov);
 
     if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
@@ -119,6 +125,11 @@
         dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
                                   dbs->iov.size / 512, dma_bdrv_cb, dbs);
     }
+    if (!dbs->acb) {
+        dma_bdrv_unmap(dbs);
+        qemu_iovec_destroy(&dbs->iov);
+        return;
+    }
 }
 
 static BlockDriverAIOCB *dma_bdrv_io(
@@ -138,6 +149,10 @@
     dbs->bh = NULL;
     qemu_iovec_init(&dbs->iov, sg->nsg);
     dma_bdrv_cb(dbs, 0);
+    if (!dbs->acb) {
+        qemu_aio_release(dbs);
+        return NULL;
+    }
     return &dbs->common;
 }
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]