Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -420,26 +420,22 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size)
static int xlvbd_barrier(struct blkfront_info *info)
{
	int err;
	unsigned ordered = QUEUE_ORDERED_NONE;
	const char *barrier;

	/*
	 * If we don't have barrier support, then there's really no
	 * way to guarantee write ordering, so we really just have to
	 * send writes to the backend and hope for the best.  If
	 * barriers are supported then we can treat them as proper
	 * ordering tags.
	 */
	if (info->feature_barrier)
		ordered = QUEUE_ORDERED_TAG;
	switch (info->feature_barrier) {
	case QUEUE_ORDERED_DRAIN:	barrier = "enabled (drain)"; break;
	case QUEUE_ORDERED_TAG:		barrier = "enabled (tag)"; break;
	case QUEUE_ORDERED_NONE:	barrier = "disabled"; break;
	default:			return -EINVAL;
	}

	err = blk_queue_ordered(info->rq, ordered);
	err = blk_queue_ordered(info->rq, info->feature_barrier);

	if (err)
		return err;

	printk(KERN_INFO "blkfront: %s: barriers %s\n",
	       info->gd->disk_name,
	       info->feature_barrier ? "enabled" : "disabled");
	       info->gd->disk_name, barrier);
	return 0;
}

@@ -665,7 +661,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
				printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
				       info->gd->disk_name);
				error = -EOPNOTSUPP;
				info->feature_barrier = 0;
				info->feature_barrier = QUEUE_ORDERED_NONE;
				xlvbd_barrier(info);
			}
			/* fall through */
@@ -1003,6 +999,7 @@ static void blkfront_connect(struct blkfront_info *info)
	unsigned long sector_size;
	unsigned int binfo;
	int err;
	int barrier;

	switch (info->connected) {
	case BLKIF_STATE_CONNECTED:
@@ -1043,10 +1040,26 @@ static void blkfront_connect(struct blkfront_info *info)
	}

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-barrier", "%lu", &info->feature_barrier,
			    "feature-barrier", "%lu", &barrier,
			    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)
		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);
	if (err) {