Commit 7403b14eeb4670d54497284b110ca3e3be4a99a4

Authored by aliguori
1 parent c240b9af

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 <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6893 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 21 additions and 6 deletions
dma-helpers.c
... ... @@ -70,20 +70,26 @@ static void continue_after_map_failure(void *opaque)
70 70 qemu_bh_schedule(dbs->bh);
71 71 }
72 72  
73   -static void dma_bdrv_cb(void *opaque, int ret)
  73 +static void dma_bdrv_unmap(DMAAIOCB *dbs)
74 74 {
75   - DMAAIOCB *dbs = (DMAAIOCB *)opaque;
76   - target_phys_addr_t cur_addr, cur_len;
77   - void *mem;
78 75 int i;
79 76  
80   - dbs->acb = NULL;
81   - dbs->sector_num += dbs->iov.size / 512;
82 77 for (i = 0; i < dbs->iov.niov; ++i) {
83 78 cpu_physical_memory_unmap(dbs->iov.iov[i].iov_base,
84 79 dbs->iov.iov[i].iov_len, !dbs->is_write,
85 80 dbs->iov.iov[i].iov_len);
86 81 }
  82 +}
  83 +
  84 +void dma_bdrv_cb(void *opaque, int ret)
  85 +{
  86 + DMAAIOCB *dbs = (DMAAIOCB *)opaque;
  87 + target_phys_addr_t cur_addr, cur_len;
  88 + void *mem;
  89 +
  90 + dbs->acb = NULL;
  91 + dbs->sector_num += dbs->iov.size / 512;
  92 + dma_bdrv_unmap(dbs);
87 93 qemu_iovec_reset(&dbs->iov);
88 94  
89 95 if (dbs->sg_cur_index == dbs->sg->nsg || ret < 0) {
... ... @@ -119,6 +125,11 @@ static void dma_bdrv_cb(void *opaque, int ret)
119 125 dbs->acb = bdrv_aio_readv(dbs->bs, dbs->sector_num, &dbs->iov,
120 126 dbs->iov.size / 512, dma_bdrv_cb, dbs);
121 127 }
  128 + if (!dbs->acb) {
  129 + dma_bdrv_unmap(dbs);
  130 + qemu_iovec_destroy(&dbs->iov);
  131 + return;
  132 + }
122 133 }
123 134  
124 135 static BlockDriverAIOCB *dma_bdrv_io(
... ... @@ -138,6 +149,10 @@ static BlockDriverAIOCB *dma_bdrv_io(
138 149 dbs->bh = NULL;
139 150 qemu_iovec_init(&dbs->iov, sg->nsg);
140 151 dma_bdrv_cb(dbs, 0);
  152 + if (!dbs->acb) {
  153 + qemu_aio_release(dbs);
  154 + return NULL;
  155 + }
141 156 return &dbs->common;
142 157 }
143 158  
... ...