aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>2010-07-28 13:49:29 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:52:53 -0400
commit7901d14144311c930918b1222aae7611284c63eb (patch)
tree53e882fd0b0588b0c43c2935d634ea97a9e1c9ed /drivers/block
parent4dab46ff26c6003a13ec769312c50938b93c359d (diff)
xen/blkfront: Use QUEUE_ORDERED_DRAIN for old backends
If there's no feature-barrier key in xenstore, then it means its a fairly old backend which does uncached in-order writes, which means ORDERED_DRAIN is appropriate. Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/xen-blkfront.c45
1 files changed, 29 insertions, 16 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 6d912ab47292..ae5f92b5752e 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -420,26 +420,22 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
420static int xlvbd_barrier(struct blkfront_info *info) 420static int xlvbd_barrier(struct blkfront_info *info)
421{ 421{
422 int err; 422 int err;
423 unsigned ordered = QUEUE_ORDERED_NONE; 423 const char *barrier;
424 424
425 /* 425 switch (info->feature_barrier) {
426 * If we don't have barrier support, then there's really no 426 case QUEUE_ORDERED_DRAIN: barrier = "enabled (drain)"; break;
427 * way to guarantee write ordering, so we really just have to 427 case QUEUE_ORDERED_TAG: barrier = "enabled (tag)"; break;
428 * send writes to the backend and hope for the best. If 428 case QUEUE_ORDERED_NONE: barrier = "disabled"; break;
429 * barriers are supported then we can treat them as proper 429 default: return -EINVAL;
430 * ordering tags. 430 }
431 */
432 if (info->feature_barrier)
433 ordered = QUEUE_ORDERED_TAG;
434 431
435 err = blk_queue_ordered(info->rq, ordered); 432 err = blk_queue_ordered(info->rq, info->feature_barrier);
436 433
437 if (err) 434 if (err)
438 return err; 435 return err;
439 436
440 printk(KERN_INFO "blkfront: %s: barriers %s\n", 437 printk(KERN_INFO "blkfront: %s: barriers %s\n",
441 info->gd->disk_name, 438 info->gd->disk_name, barrier);
442 info->feature_barrier ? "enabled" : "disabled");
443 return 0; 439 return 0;
444} 440}
445 441
@@ -665,7 +661,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
665 printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", 661 printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
666 info->gd->disk_name); 662 info->gd->disk_name);
667 error = -EOPNOTSUPP; 663 error = -EOPNOTSUPP;
668 info->feature_barrier = 0; 664 info->feature_barrier = QUEUE_ORDERED_NONE;
669 xlvbd_barrier(info); 665 xlvbd_barrier(info);
670 } 666 }
671 /* fall through */ 667 /* fall through */
@@ -1003,6 +999,7 @@ static void blkfront_connect(struct blkfront_info *info)
1003 unsigned long sector_size; 999 unsigned long sector_size;
1004 unsigned int binfo; 1000 unsigned int binfo;
1005 int err; 1001 int err;
1002 int barrier;
1006 1003
1007 switch (info->connected) { 1004 switch (info->connected) {
1008 case BLKIF_STATE_CONNECTED: 1005 case BLKIF_STATE_CONNECTED:
@@ -1043,10 +1040,26 @@ static void blkfront_connect(struct blkfront_info *info)
1043 } 1040 }
1044 1041
1045 err = xenbus_gather(XBT_NIL, info->xbdev->otherend, 1042 err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
1046 "feature-barrier", "%lu", &info->feature_barrier, 1043 "feature-barrier", "%lu", &barrier,
1047 NULL); 1044 NULL);
1045
1046 /*
1047 * If there's no "feature-barrier" defined, then it means
1048 * we're dealing with a very old backend which writes
1049 * synchronously; draining will do what needs to get done.
1050 *
1051 * If there are barriers, then we can do full queued writes
1052 * with tagged barriers.
1053 *
1054 * If barriers are not supported, then there's no much we can
1055 * do, so just set ordering to NONE.
1056 */
1048 if (err) 1057 if (err)
1049 info->feature_barrier = 0; 1058 info->feature_barrier = QUEUE_ORDERED_DRAIN;
1059 else if (barrier)
1060 info->feature_barrier = QUEUE_ORDERED_TAG;
1061 else
1062 info->feature_barrier = QUEUE_ORDERED_NONE;
1050 1063
1051 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); 1064 err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
1052 if (err) { 1065 if (err) {