diff options
Diffstat (limited to 'drivers/block/xen-blkback/blkback.c')
-rw-r--r-- | drivers/block/xen-blkback/blkback.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 4119bcdefd1a..ea158fe0c9a4 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c | |||
@@ -571,6 +571,7 @@ int xen_blkif_schedule(void *arg) | |||
571 | struct xen_blkif *blkif = arg; | 571 | struct xen_blkif *blkif = arg; |
572 | struct xen_vbd *vbd = &blkif->vbd; | 572 | struct xen_vbd *vbd = &blkif->vbd; |
573 | unsigned long timeout; | 573 | unsigned long timeout; |
574 | int ret; | ||
574 | 575 | ||
575 | xen_blkif_get(blkif); | 576 | xen_blkif_get(blkif); |
576 | 577 | ||
@@ -599,8 +600,12 @@ int xen_blkif_schedule(void *arg) | |||
599 | blkif->waiting_reqs = 0; | 600 | blkif->waiting_reqs = 0; |
600 | smp_mb(); /* clear flag *before* checking for work */ | 601 | smp_mb(); /* clear flag *before* checking for work */ |
601 | 602 | ||
602 | if (do_block_io_op(blkif)) | 603 | ret = do_block_io_op(blkif); |
604 | if (ret > 0) | ||
603 | blkif->waiting_reqs = 1; | 605 | blkif->waiting_reqs = 1; |
606 | if (ret == -EACCES) | ||
607 | wait_event_interruptible(blkif->shutdown_wq, | ||
608 | kthread_should_stop()); | ||
604 | 609 | ||
605 | purge_gnt_list: | 610 | purge_gnt_list: |
606 | if (blkif->vbd.feature_gnt_persistent && | 611 | if (blkif->vbd.feature_gnt_persistent && |
@@ -1009,6 +1014,12 @@ __do_block_io_op(struct xen_blkif *blkif) | |||
1009 | rp = blk_rings->common.sring->req_prod; | 1014 | rp = blk_rings->common.sring->req_prod; |
1010 | rmb(); /* Ensure we see queued requests up to 'rp'. */ | 1015 | rmb(); /* Ensure we see queued requests up to 'rp'. */ |
1011 | 1016 | ||
1017 | if (RING_REQUEST_PROD_OVERFLOW(&blk_rings->common, rp)) { | ||
1018 | rc = blk_rings->common.rsp_prod_pvt; | ||
1019 | pr_warn(DRV_PFX "Frontend provided bogus ring requests (%d - %d = %d). Halting ring processing on dev=%04x\n", | ||
1020 | rp, rc, rp - rc, blkif->vbd.pdevice); | ||
1021 | return -EACCES; | ||
1022 | } | ||
1012 | while (rc != rp) { | 1023 | while (rc != rp) { |
1013 | 1024 | ||
1014 | if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) | 1025 | if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc)) |