diff options
| -rw-r--r-- | drivers/block/xen-blkfront.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 2e6c10371b24..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 | } |
| @@ -685,20 +696,26 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size, | |||
| 685 | return 0; | 696 | return 0; |
| 686 | } | 697 | } |
| 687 | 698 | ||
| 699 | static 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 | } | ||
| 688 | 710 | ||
| 689 | static void xlvbd_flush(struct blkfront_info *info) | 711 | static void xlvbd_flush(struct blkfront_info *info) |
| 690 | { | 712 | { |
| 691 | blk_queue_flush(info->rq, info->feature_flush); | 713 | blk_queue_flush(info->rq, info->feature_flush); |
| 692 | printk(KERN_INFO "blkfront: %s: %s: %s %s %s %s %s\n", | 714 | pr_info("blkfront: %s: %s %s %s %s %s\n", |
| 693 | info->gd->disk_name, | 715 | info->gd->disk_name, flush_info(info->feature_flush), |
| 694 | info->flush_op == BLKIF_OP_WRITE_BARRIER ? | 716 | "persistent grants:", info->feature_persistent ? |
| 695 | "barrier" : (info->flush_op == BLKIF_OP_FLUSH_DISKCACHE ? | 717 | "enabled;" : "disabled;", "indirect descriptors:", |
| 696 | "flush diskcache" : "barrier or flush"), | 718 | info->max_indirect_segments ? "enabled;" : "disabled;"); |
| 697 | info->feature_flush ? "enabled;" : "disabled;", | ||
| 698 | "persistent grants:", | ||
| 699 | info->feature_persistent ? "enabled;" : "disabled;", | ||
| 700 | "indirect descriptors:", | ||
| 701 | info->max_indirect_segments ? "enabled;" : "disabled;"); | ||
| 702 | } | 719 | } |
| 703 | 720 | ||
| 704 | static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) | 721 | static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) |
| @@ -1190,7 +1207,6 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) | |||
| 1190 | if (error == -EOPNOTSUPP) | 1207 | if (error == -EOPNOTSUPP) |
| 1191 | error = 0; | 1208 | error = 0; |
| 1192 | info->feature_flush = 0; | 1209 | info->feature_flush = 0; |
| 1193 | info->flush_op = 0; | ||
| 1194 | xlvbd_flush(info); | 1210 | xlvbd_flush(info); |
| 1195 | } | 1211 | } |
| 1196 | /* fall through */ | 1212 | /* fall through */ |
| @@ -1810,7 +1826,6 @@ static void blkfront_connect(struct blkfront_info *info) | |||
| 1810 | physical_sector_size = sector_size; | 1826 | physical_sector_size = sector_size; |
| 1811 | 1827 | ||
| 1812 | info->feature_flush = 0; | 1828 | info->feature_flush = 0; |
| 1813 | info->flush_op = 0; | ||
| 1814 | 1829 | ||
| 1815 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | 1830 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, |
| 1816 | "feature-barrier", "%d", &barrier, | 1831 | "feature-barrier", "%d", &barrier, |
| @@ -1823,10 +1838,8 @@ static void blkfront_connect(struct blkfront_info *info) | |||
| 1823 | * | 1838 | * |
| 1824 | * If there are barriers, then we use flush. | 1839 | * If there are barriers, then we use flush. |
| 1825 | */ | 1840 | */ |
| 1826 | if (!err && barrier) { | 1841 | if (!err && barrier) |
| 1827 | info->feature_flush = REQ_FLUSH | REQ_FUA; | 1842 | info->feature_flush = REQ_FLUSH | REQ_FUA; |
| 1828 | info->flush_op = BLKIF_OP_WRITE_BARRIER; | ||
| 1829 | } | ||
| 1830 | /* | 1843 | /* |
| 1831 | * And if there is "feature-flush-cache" use that above | 1844 | * And if there is "feature-flush-cache" use that above |
| 1832 | * barriers. | 1845 | * barriers. |
| @@ -1835,10 +1848,8 @@ static void blkfront_connect(struct blkfront_info *info) | |||
| 1835 | "feature-flush-cache", "%d", &flush, | 1848 | "feature-flush-cache", "%d", &flush, |
| 1836 | NULL); | 1849 | NULL); |
| 1837 | 1850 | ||
| 1838 | if (!err && flush) { | 1851 | if (!err && flush) |
| 1839 | info->feature_flush = REQ_FLUSH; | 1852 | info->feature_flush = REQ_FLUSH; |
| 1840 | info->flush_op = BLKIF_OP_FLUSH_DISKCACHE; | ||
| 1841 | } | ||
| 1842 | 1853 | ||
| 1843 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, | 1854 | err = xenbus_gather(XBT_NIL, info->xbdev->otherend, |
| 1844 | "feature-discard", "%d", &discard, | 1855 | "feature-discard", "%d", &discard, |
