aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-12-10 15:58:17 -0500
committerJens Axboe <axboe@fb.com>2014-12-10 15:58:17 -0500
commitd8ead9b763cab553f82a6f16015d3ace5f9c6653 (patch)
tree76743bcb34cfe103b759cc7f9d4a6dc1f15404c6 /drivers/block
parent97fe383222cb8a01fb67a8823498ad2edcc20b35 (diff)
parentfdf9b9650366c575650edcaaede3a68efbb24919 (diff)
Merge branch 'for-jens-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen into for-3.19/drivers
Konrad writes: These are two fixes for Xen blkfront. They harden how it deals with broken backends.
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/xen-blkfront.c65
1 files changed, 39 insertions, 26 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 5ac312f6e0be..2236c6f31608 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -126,7 +126,6 @@ struct blkfront_info
126 unsigned int persistent_gnts_c; 126 unsigned int persistent_gnts_c;
127 unsigned long shadow_free; 127 unsigned long shadow_free;
128 unsigned int feature_flush; 128 unsigned int feature_flush;
129 unsigned int flush_op;
130 unsigned int feature_discard:1; 129 unsigned int feature_discard:1;
131 unsigned int feature_secdiscard:1; 130 unsigned int feature_secdiscard:1;
132 unsigned int discard_granularity; 131 unsigned int discard_granularity;
@@ -479,7 +478,19 @@ static int blkif_queue_request(struct request *req)
479 * way. (It's also a FLUSH+FUA, since it is 478 * way. (It's also a FLUSH+FUA, since it is
480 * guaranteed ordered WRT previous writes.) 479 * guaranteed ordered WRT previous writes.)
481 */ 480 */
482 ring_req->operation = info->flush_op; 481 switch (info->feature_flush &
482 ((REQ_FLUSH|REQ_FUA))) {
483 case REQ_FLUSH|REQ_FUA:
484 ring_req->operation =
485 BLKIF_OP_WRITE_BARRIER;
486 break;
487 case REQ_FLUSH:
488 ring_req->operation =
489 BLKIF_OP_FLUSH_DISKCACHE;
490 break;
491 default:
492 ring_req->operation = 0;
493 }
483 } 494 }
484 ring_req->u.rw.nr_segments = nseg; 495 ring_req->u.rw.nr_segments = nseg;
485 } 496 }
@@ -582,12 +593,14 @@ static inline void flush_requests(struct blkfront_info *info)
582 notify_remote_via_irq(info->irq); 593 notify_remote_via_irq(info->irq);
583} 594}
584 595
585static inline bool blkif_request_flush_valid(struct request *req, 596static inline bool blkif_request_flush_invalid(struct request *req,
586 struct blkfront_info *info) 597 struct blkfront_info *info)
587{ 598{
588 return ((req->cmd_type != REQ_TYPE_FS) || 599 return ((req->cmd_type != REQ_TYPE_FS) ||
589 ((req->cmd_flags & (REQ_FLUSH | REQ_FUA)) && 600 ((req->cmd_flags & REQ_FLUSH) &&
590 !info->flush_op)); 601 !(info->feature_flush & REQ_FLUSH)) ||
602 ((req->cmd_flags & REQ_FUA) &&
603 !(info->feature_flush & REQ_FUA)));
591} 604}
592 605
593/* 606/*
@@ -612,8 +625,8 @@ static void do_blkif_request(struct request_queue *rq)
612 625
613 blk_start_request(req); 626 blk_start_request(req);
614 627
615 if (blkif_request_flush_valid(req, info)) { 628 if (blkif_request_flush_invalid(req, info)) {
616 __blk_end_request_all(req, -EIO); 629 __blk_end_request_all(req, -EOPNOTSUPP);
617 continue; 630 continue;
618 } 631 }
619 632
@@ -683,20 +696,26 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
683 return 0; 696 return 0;
684} 697}
685 698
699static const char *flush_info(unsigned int feature_flush)
700{
701 switch (feature_flush & ((REQ_FLUSH | REQ_FUA))) {
702 case REQ_FLUSH|REQ_FUA:
703 return "barrier: enabled;";
704 case REQ_FLUSH:
705 return "flush diskcache: enabled;";
706 default:
707 return "barrier or flush: disabled;";
708 }
709}
686 710
687static void xlvbd_flush(struct blkfront_info *info) 711static void xlvbd_flush(struct blkfront_info *info)
688{ 712{
689 blk_queue_flush(info->rq, info->feature_flush); 713 blk_queue_flush(info->rq, info->feature_flush);
690 printk(KERN_INFO "blkfront: %s: %s: %s %s %s %s %s\n", 714 pr_info("blkfront: %s: %s %s %s %s %s\n",
691 info->gd->disk_name, 715 info->gd->disk_name, flush_info(info->feature_flush),
692 info->flush_op == BLKIF_OP_WRITE_BARRIER ? 716 "persistent grants:", info->feature_persistent ?
693 "barrier" : (info->flush_op == BLKIF_OP_FLUSH_DISKCACHE ? 717 "enabled;" : "disabled;", "indirect descriptors:",
694 "flush diskcache" : "barrier or flush"), 718 info->max_indirect_segments ? "enabled;" : "disabled;");
695 info->feature_flush ? "enabled;" : "disabled;",
696 "persistent grants:",
697 info->feature_persistent ? "enabled;" : "disabled;",
698 "indirect descriptors:",
699 info->max_indirect_segments ? "enabled;" : "disabled;");
700} 719}
701 720
702static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) 721static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
@@ -1188,7 +1207,6 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
1188 if (error == -EOPNOTSUPP) 1207 if (error == -EOPNOTSUPP)
1189 error = 0; 1208 error = 0;
1190 info->feature_flush = 0; 1209 info->feature_flush = 0;
1191 info->flush_op = 0;
1192 xlvbd_flush(info); 1210 xlvbd_flush(info);
1193 } 1211 }
1194 /* fall through */ 1212 /* fall through */
@@ -1808,7 +1826,6 @@ static void blkfront_connect(struct blkfront_info *info)
1808 physical_sector_size = sector_size; 1826 physical_sector_size = sector_size;
1809 1827
1810 info->feature_flush = 0; 1828 info->feature_flush = 0;
1811 info->flush_op = 0;
1812 1829
1813 err = xenbus_gather(XBT_NIL, info->xbdev->otherend, 1830 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1814 "feature-barrier", "%d", &barrier, 1831 "feature-barrier", "%d", &barrier,
@@ -1821,10 +1838,8 @@ static void blkfront_connect(struct blkfront_info *info)
1821 * 1838 *
1822 * If there are barriers, then we use flush. 1839 * If there are barriers, then we use flush.
1823 */ 1840 */
1824 if (!err && barrier) { 1841 if (!err && barrier)
1825 info->feature_flush = REQ_FLUSH | REQ_FUA; 1842 info->feature_flush = REQ_FLUSH | REQ_FUA;
1826 info->flush_op = BLKIF_OP_WRITE_BARRIER;
1827 }
1828 /* 1843 /*
1829 * And if there is "feature-flush-cache" use that above 1844 * And if there is "feature-flush-cache" use that above
1830 * barriers. 1845 * barriers.
@@ -1833,10 +1848,8 @@ static void blkfront_connect(struct blkfront_info *info)
1833 "feature-flush-cache", "%d", &flush, 1848 "feature-flush-cache", "%d", &flush,
1834 NULL); 1849 NULL);
1835 1850
1836 if (!err && flush) { 1851 if (!err && flush)
1837 info->feature_flush = REQ_FLUSH; 1852 info->feature_flush = REQ_FLUSH;
1838 info->flush_op = BLKIF_OP_FLUSH_DISKCACHE;
1839 }
1840 1853
1841 err = xenbus_gather(XBT_NIL, info->xbdev->otherend, 1854 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1842 "feature-discard", "%d", &discard, 1855 "feature-discard", "%d", &discard,