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.c68
1 files changed, 39 insertions, 29 deletions
diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c
index de1f319f7bd7..dd5b2fed97e9 100644
--- a/drivers/block/xen-blkback/blkback.c
+++ b/drivers/block/xen-blkback/blkback.c
@@ -164,7 +164,7 @@ static void make_response(struct xen_blkif *blkif, u64 id,
164 164
165#define foreach_grant_safe(pos, n, rbtree, node) \ 165#define foreach_grant_safe(pos, n, rbtree, node) \
166 for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \ 166 for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \
167 (n) = rb_next(&(pos)->node); \ 167 (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL; \
168 &(pos)->node != NULL; \ 168 &(pos)->node != NULL; \
169 (pos) = container_of(n, typeof(*(pos)), node), \ 169 (pos) = container_of(n, typeof(*(pos)), node), \
170 (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL) 170 (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL)
@@ -381,8 +381,8 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
381 381
382static void print_stats(struct xen_blkif *blkif) 382static void print_stats(struct xen_blkif *blkif)
383{ 383{
384 pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d" 384 pr_info("xen-blkback (%s): oo %3llu | rd %4llu | wr %4llu | f %4llu"
385 " | ds %4d\n", 385 " | ds %4llu\n",
386 current->comm, blkif->st_oo_req, 386 current->comm, blkif->st_oo_req,
387 blkif->st_rd_req, blkif->st_wr_req, 387 blkif->st_rd_req, blkif->st_wr_req,
388 blkif->st_f_req, blkif->st_ds_req); 388 blkif->st_f_req, blkif->st_ds_req);
@@ -442,7 +442,7 @@ int xen_blkif_schedule(void *arg)
442} 442}
443 443
444struct seg_buf { 444struct seg_buf {
445 unsigned long buf; 445 unsigned int offset;
446 unsigned int nsec; 446 unsigned int nsec;
447}; 447};
448/* 448/*
@@ -621,30 +621,21 @@ static int xen_blkbk_map(struct blkif_request *req,
621 * If this is a new persistent grant 621 * If this is a new persistent grant
622 * save the handler 622 * save the handler
623 */ 623 */
624 persistent_gnts[i]->handle = map[j].handle; 624 persistent_gnts[i]->handle = map[j++].handle;
625 persistent_gnts[i]->dev_bus_addr =
626 map[j++].dev_bus_addr;
627 } 625 }
628 pending_handle(pending_req, i) = 626 pending_handle(pending_req, i) =
629 persistent_gnts[i]->handle; 627 persistent_gnts[i]->handle;
630 628
631 if (ret) 629 if (ret)
632 continue; 630 continue;
633
634 seg[i].buf = persistent_gnts[i]->dev_bus_addr |
635 (req->u.rw.seg[i].first_sect << 9);
636 } else { 631 } else {
637 pending_handle(pending_req, i) = map[j].handle; 632 pending_handle(pending_req, i) = map[j++].handle;
638 bitmap_set(pending_req->unmap_seg, i, 1); 633 bitmap_set(pending_req->unmap_seg, i, 1);
639 634
640 if (ret) { 635 if (ret)
641 j++;
642 continue; 636 continue;
643 }
644
645 seg[i].buf = map[j++].dev_bus_addr |
646 (req->u.rw.seg[i].first_sect << 9);
647 } 637 }
638 seg[i].offset = (req->u.rw.seg[i].first_sect << 9);
648 } 639 }
649 return ret; 640 return ret;
650} 641}
@@ -679,6 +670,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif,
679 return err; 670 return err;
680} 671}
681 672
673static int dispatch_other_io(struct xen_blkif *blkif,
674 struct blkif_request *req,
675 struct pending_req *pending_req)
676{
677 free_req(pending_req);
678 make_response(blkif, req->u.other.id, req->operation,
679 BLKIF_RSP_EOPNOTSUPP);
680 return -EIO;
681}
682
682static void xen_blk_drain_io(struct xen_blkif *blkif) 683static void xen_blk_drain_io(struct xen_blkif *blkif)
683{ 684{
684 atomic_set(&blkif->drain, 1); 685 atomic_set(&blkif->drain, 1);
@@ -800,17 +801,30 @@ __do_block_io_op(struct xen_blkif *blkif)
800 801
801 /* Apply all sanity checks to /private copy/ of request. */ 802 /* Apply all sanity checks to /private copy/ of request. */
802 barrier(); 803 barrier();
803 if (unlikely(req.operation == BLKIF_OP_DISCARD)) { 804
805 switch (req.operation) {
806 case BLKIF_OP_READ:
807 case BLKIF_OP_WRITE:
808 case BLKIF_OP_WRITE_BARRIER:
809 case BLKIF_OP_FLUSH_DISKCACHE:
810 if (dispatch_rw_block_io(blkif, &req, pending_req))
811 goto done;
812 break;
813 case BLKIF_OP_DISCARD:
804 free_req(pending_req); 814 free_req(pending_req);
805 if (dispatch_discard_io(blkif, &req)) 815 if (dispatch_discard_io(blkif, &req))
806 break; 816 goto done;
807 } else if (dispatch_rw_block_io(blkif, &req, pending_req))
808 break; 817 break;
818 default:
819 if (dispatch_other_io(blkif, &req, pending_req))
820 goto done;
821 break;
822 }
809 823
810 /* Yield point for this unbounded loop. */ 824 /* Yield point for this unbounded loop. */
811 cond_resched(); 825 cond_resched();
812 } 826 }
813 827done:
814 return more_to_do; 828 return more_to_do;
815} 829}
816 830
@@ -904,7 +918,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
904 pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n", 918 pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n",
905 operation == READ ? "read" : "write", 919 operation == READ ? "read" : "write",
906 preq.sector_number, 920 preq.sector_number,
907 preq.sector_number + preq.nr_sects, preq.dev); 921 preq.sector_number + preq.nr_sects,
922 blkif->vbd.pdevice);
908 goto fail_response; 923 goto fail_response;
909 } 924 }
910 925
@@ -947,7 +962,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
947 (bio_add_page(bio, 962 (bio_add_page(bio,
948 pages[i], 963 pages[i],
949 seg[i].nsec << 9, 964 seg[i].nsec << 9,
950 seg[i].buf & ~PAGE_MASK) == 0)) { 965 seg[i].offset) == 0)) {
951 966
952 bio = bio_alloc(GFP_KERNEL, nseg-i); 967 bio = bio_alloc(GFP_KERNEL, nseg-i);
953 if (unlikely(bio == NULL)) 968 if (unlikely(bio == NULL))
@@ -977,13 +992,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
977 bio->bi_end_io = end_block_io_op; 992 bio->bi_end_io = end_block_io_op;
978 } 993 }
979 994
980 /*
981 * We set it one so that the last submit_bio does not have to call
982 * atomic_inc.
983 */
984 atomic_set(&pending_req->pendcnt, nbio); 995 atomic_set(&pending_req->pendcnt, nbio);
985
986 /* Get a reference count for the disk queue and start sending I/O */
987 blk_start_plug(&plug); 996 blk_start_plug(&plug);
988 997
989 for (i = 0; i < nbio; i++) 998 for (i = 0; i < nbio; i++)
@@ -1011,6 +1020,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif,
1011 fail_put_bio: 1020 fail_put_bio:
1012 for (i = 0; i < nbio; i++) 1021 for (i = 0; i < nbio; i++)
1013 bio_put(biolist[i]); 1022 bio_put(biolist[i]);
1023 atomic_set(&pending_req->pendcnt, 1);
1014 __end_block_io_op(pending_req, -EINVAL); 1024 __end_block_io_op(pending_req, -EINVAL);
1015 msleep(1); /* back off a bit */ 1025 msleep(1); /* back off a bit */
1016 return -EIO; 1026 return -EIO;