aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/xen-blkfront.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/xen-blkfront.c')
-rw-r--r--drivers/block/xen-blkfront.c54
1 files changed, 20 insertions, 34 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 3ff06f475ee..4b33a18c32e 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -96,7 +96,7 @@ struct blkfront_info
96 struct gnttab_free_callback callback; 96 struct gnttab_free_callback callback;
97 struct blk_shadow shadow[BLK_RING_SIZE]; 97 struct blk_shadow shadow[BLK_RING_SIZE];
98 unsigned long shadow_free; 98 unsigned long shadow_free;
99 int feature_barrier; 99 unsigned int feature_flush;
100 int is_ready; 100 int is_ready;
101}; 101};
102 102
@@ -419,26 +419,12 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
419} 419}
420 420
421 421
422static int xlvbd_barrier(struct blkfront_info *info) 422static void xlvbd_flush(struct blkfront_info *info)
423{ 423{
424 int err; 424 blk_queue_flush(info->rq, info->feature_flush);
425 const char *barrier;
426
427 switch (info->feature_barrier) {
428 case QUEUE_ORDERED_DRAIN: barrier = "enabled (drain)"; break;
429 case QUEUE_ORDERED_TAG: barrier = "enabled (tag)"; break;
430 case QUEUE_ORDERED_NONE: barrier = "disabled"; break;
431 default: return -EINVAL;
432 }
433
434 err = blk_queue_ordered(info->rq, info->feature_barrier);
435
436 if (err)
437 return err;
438
439 printk(KERN_INFO "blkfront: %s: barriers %s\n", 425 printk(KERN_INFO "blkfront: %s: barriers %s\n",
440 info->gd->disk_name, barrier); 426 info->gd->disk_name,
441 return 0; 427 info->feature_flush ? "enabled" : "disabled");
442} 428}
443 429
444 430
@@ -517,7 +503,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
517 info->rq = gd->queue; 503 info->rq = gd->queue;
518 info->gd = gd; 504 info->gd = gd;
519 505
520 xlvbd_barrier(info); 506 xlvbd_flush(info);
521 507
522 if (vdisk_info & VDISK_READONLY) 508 if (vdisk_info & VDISK_READONLY)
523 set_disk_ro(gd, 1); 509 set_disk_ro(gd, 1);
@@ -663,8 +649,8 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
663 printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", 649 printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
664 info->gd->disk_name); 650 info->gd->disk_name);
665 error = -EOPNOTSUPP; 651 error = -EOPNOTSUPP;
666 info->feature_barrier = QUEUE_ORDERED_NONE; 652 info->feature_flush = 0;
667 xlvbd_barrier(info); 653 xlvbd_flush(info);
668 } 654 }
669 /* fall through */ 655 /* fall through */
670 case BLKIF_OP_READ: 656 case BLKIF_OP_READ:
@@ -1077,20 +1063,20 @@ static void blkfront_connect(struct blkfront_info *info)
1077 /* 1063 /*
1078 * If there's no "feature-barrier" defined, then it means 1064 * If there's no "feature-barrier" defined, then it means
1079 * we're dealing with a very old backend which writes 1065 * we're dealing with a very old backend which writes
1080 * synchronously; draining will do what needs to get done. 1066 * synchronously; nothing to do.
1081 * 1067 *
1082 * If there are barriers, then we can do full queued writes 1068 * If there are barriers, then we use flush.
1083 * with tagged barriers.
1084 *
1085 * If barriers are not supported, then there's no much we can
1086 * do, so just set ordering to NONE.
1087 */ 1069 */
1088 if (err) 1070 info->feature_flush = 0;
1089 info->feature_barrier = QUEUE_ORDERED_DRAIN; 1071
1090 else if (barrier) 1072 /*
1091 info->feature_barrier = QUEUE_ORDERED_TAG; 1073 * The driver doesn't properly handled empty flushes, so
1092 else 1074 * lets disable barrier support for now.
1093 info->feature_barrier = QUEUE_ORDERED_NONE; 1075 */
1076#if 0
1077 if (!err && barrier)
1078 info->feature_flush = REQ_FLUSH;
1079#endif
1094 1080
1095 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); 1081 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
1096 if (err) { 1082 if (err) {