Commit 7901d141 authored by Jeremy Fitzhardinge's avatar Jeremy Fitzhardinge Committed by Jens Axboe

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: default avatarJeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
parent 4dab46ff
...@@ -420,26 +420,22 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size) ...@@ -420,26 +420,22 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
static int xlvbd_barrier(struct blkfront_info *info) static int xlvbd_barrier(struct blkfront_info *info)
{ {
int err; int err;
unsigned ordered = QUEUE_ORDERED_NONE; const char *barrier;
/* switch (info->feature_barrier) {
* If we don't have barrier support, then there's really no case QUEUE_ORDERED_DRAIN: barrier = "enabled (drain)"; break;
* way to guarantee write ordering, so we really just have to case QUEUE_ORDERED_TAG: barrier = "enabled (tag)"; break;
* send writes to the backend and hope for the best. If case QUEUE_ORDERED_NONE: barrier = "disabled"; break;
* barriers are supported then we can treat them as proper default: return -EINVAL;
* ordering tags. }
*/
if (info->feature_barrier)
ordered = QUEUE_ORDERED_TAG;
err = blk_queue_ordered(info->rq, ordered); err = blk_queue_ordered(info->rq, info->feature_barrier);
if (err) if (err)
return err; return err;
printk(KERN_INFO "blkfront: %s: barriers %s\n", printk(KERN_INFO "blkfront: %s: barriers %s\n",
info->gd->disk_name, info->gd->disk_name, barrier);
info->feature_barrier ? "enabled" : "disabled");
return 0; return 0;
} }
...@@ -665,7 +661,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id) ...@@ -665,7 +661,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
printk(KERN_WARNING "blkfront: %s: write barrier op failed\n", printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
info->gd->disk_name); info->gd->disk_name);
error = -EOPNOTSUPP; error = -EOPNOTSUPP;
info->feature_barrier = 0; info->feature_barrier = QUEUE_ORDERED_NONE;
xlvbd_barrier(info); xlvbd_barrier(info);
} }
/* fall through */ /* fall through */
...@@ -1003,6 +999,7 @@ static void blkfront_connect(struct blkfront_info *info) ...@@ -1003,6 +999,7 @@ static void blkfront_connect(struct blkfront_info *info)
unsigned long sector_size; unsigned long sector_size;
unsigned int binfo; unsigned int binfo;
int err; int err;
int barrier;
switch (info->connected) { switch (info->connected) {
case BLKIF_STATE_CONNECTED: case BLKIF_STATE_CONNECTED:
...@@ -1043,10 +1040,26 @@ static void blkfront_connect(struct blkfront_info *info) ...@@ -1043,10 +1040,26 @@ static void blkfront_connect(struct blkfront_info *info)
} }
err = xenbus_gather(XBT_NIL, info->xbdev->otherend, err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
"feature-barrier", "%lu", &info->feature_barrier, "feature-barrier", "%lu", &barrier,
NULL); NULL);
/*
* If there's no "feature-barrier" defined, then it means
* we're dealing with a very old backend which writes
* synchronously; draining will do what needs to get done.
*
* If there are barriers, then we can do full queued writes
* with tagged barriers.
*
* If barriers are not supported, then there's no much we can
* do, so just set ordering to NONE.
*/
if (err) if (err)
info->feature_barrier = 0; info->feature_barrier = QUEUE_ORDERED_DRAIN;
else if (barrier)
info->feature_barrier = QUEUE_ORDERED_TAG;
else
info->feature_barrier = QUEUE_ORDERED_NONE;
err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size); err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
if (err) { if (err) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment