aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkback/blkback.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/xen-blkback/blkback.c')
-rw-r--r--drivers/block/xen-blkback/blkback.c13
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
605purge_gnt_list: 610purge_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))