aboutsummaryrefslogtreecommitdiffstats
path: root/extras/mini-os/blkfront.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-03-26 13:15:00 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-03-26 13:15:00 +0000
commitd3ca7ebeccd4a93deea2c2eadee40c0b3be57aeb (patch)
tree57f611598b750ba7683d1ba7d2f3a4a3fe45c500 /extras/mini-os/blkfront.c
parentaecea1aa6522c44d8111731c8b6f0e9a6e08f001 (diff)
downloadxen-d3ca7ebeccd4a93deea2c2eadee40c0b3be57aeb.tar.gz
xen-d3ca7ebeccd4a93deea2c2eadee40c0b3be57aeb.tar.bz2
xen-d3ca7ebeccd4a93deea2c2eadee40c0b3be57aeb.zip
minios: blkfront_aio_poll may reenter
if the callback calls blkfront_sync for instance. In such a case, we would see responses and hence release grants several times. We need to be more synchronous and stop when we detect that we have re-entered. This fixes HVM restore with stubdomains. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'extras/mini-os/blkfront.c')
-rw-r--r--extras/mini-os/blkfront.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/extras/mini-os/blkfront.c b/extras/mini-os/blkfront.c
index 3a6c22aceb..b227f06247 100644
--- a/extras/mini-os/blkfront.c
+++ b/extras/mini-os/blkfront.c
@@ -319,6 +319,7 @@ int blkfront_aio_poll(struct blkfront_dev *dev)
{
RING_IDX rp, cons;
struct blkif_response *rsp;
+ int more;
moretodo:
#ifdef HAVE_LIBC
@@ -334,6 +335,7 @@ moretodo:
while ((cons != rp))
{
rsp = RING_GET_RESPONSE(&dev->ring, cons);
+ nr_consumed++;
if (rsp->status != BLKIF_RSP_OKAY)
printk("block error %d for op %d\n", rsp->status, rsp->operation);
@@ -343,29 +345,30 @@ moretodo:
case BLKIF_OP_WRITE:
{
struct blkfront_aiocb *aiocbp = (void*) (uintptr_t) rsp->id;
+ int status = rsp->status;
int j;
for (j = 0; j < aiocbp->n; j++)
gnttab_end_access(aiocbp->gref[j]);
+ dev->ring.rsp_cons = ++cons;
/* Nota: callback frees aiocbp itself */
- aiocbp->aio_cb(aiocbp, rsp->status ? -EIO : 0);
+ aiocbp->aio_cb(aiocbp, status ? -EIO : 0);
+ if (dev->ring.rsp_cons != cons)
+ /* We reentered, we must not continue here */
+ goto out;
break;
}
- case BLKIF_OP_WRITE_BARRIER:
- case BLKIF_OP_FLUSH_DISKCACHE:
- break;
default:
printk("unrecognized block operation %d response\n", rsp->operation);
+ case BLKIF_OP_WRITE_BARRIER:
+ case BLKIF_OP_FLUSH_DISKCACHE:
+ dev->ring.rsp_cons = ++cons;
break;
}
-
- nr_consumed++;
- ++cons;
}
- dev->ring.rsp_cons = cons;
- int more;
+out:
RING_FINAL_CHECK_FOR_RESPONSES(&dev->ring, more);
if (more) goto moretodo;