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