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

Commit ebcbf166 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull xen block driver fixes from Jens Axboe:
 "A few small bug fixes for xen-blk{front,back} that have been sitting
  over my vacation"

* 'for-linus' of git://git.kernel.dk/linux-block:
  xen-blkback: replace work_pending with work_busy in purge_persistent_gnt()
  xen-blkfront: don't add indirect pages to list when !feature_persistent
  xen-blkfront: introduce blkfront_gather_backend_features()
parents 6b476e11 e162b219
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -369,8 +369,8 @@ static void purge_persistent_gnt(struct xen_blkif *blkif)
		return;
	}

	if (work_pending(&blkif->persistent_purge_work)) {
		pr_alert_ratelimited("Scheduled work from previous purge is still pending, cannot purge list\n");
	if (work_busy(&blkif->persistent_purge_work)) {
		pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
		return;
	}

+72 −56
Original line number Diff line number Diff line
@@ -179,6 +179,7 @@ static DEFINE_SPINLOCK(minor_lock);
	((_segs + SEGS_PER_INDIRECT_FRAME - 1)/SEGS_PER_INDIRECT_FRAME)

static int blkfront_setup_indirect(struct blkfront_info *info);
static int blkfront_gather_backend_features(struct blkfront_info *info);

static int get_id_from_freelist(struct blkfront_info *info)
{
@@ -1128,8 +1129,10 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info,
				 * Add the used indirect page back to the list of
				 * available pages for indirect grefs.
				 */
				if (!info->feature_persistent) {
					indirect_page = pfn_to_page(s->indirect_grants[i]->pfn);
					list_add(&indirect_page->lru, &info->indirect_pages);
				}
				s->indirect_grants[i]->gref = GRANT_INVALID_REF;
				list_add_tail(&s->indirect_grants[i]->node, &info->grants);
			}
@@ -1519,7 +1522,7 @@ static int blkif_recover(struct blkfront_info *info)
	info->shadow_free = info->ring.req_prod_pvt;
	info->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;

	rc = blkfront_setup_indirect(info);
	rc = blkfront_gather_backend_features(info);
	if (rc) {
		kfree(copy);
		return rc;
@@ -1720,20 +1723,13 @@ static void blkfront_setup_discard(struct blkfront_info *info)

static int blkfront_setup_indirect(struct blkfront_info *info)
{
	unsigned int indirect_segments, segs;
	unsigned int segs;
	int err, i;

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-max-indirect-segments", "%u", &indirect_segments,
			    NULL);
	if (err) {
		info->max_indirect_segments = 0;
	if (info->max_indirect_segments == 0)
		segs = BLKIF_MAX_SEGMENTS_PER_REQUEST;
	} else {
		info->max_indirect_segments = min(indirect_segments,
						  xen_blkif_max_segments);
	else
		segs = info->max_indirect_segments;
	}

	err = fill_grant_buffer(info, (segs + INDIRECT_GREFS(segs)) * BLK_RING_SIZE(info));
	if (err)
@@ -1796,6 +1792,68 @@ static int blkfront_setup_indirect(struct blkfront_info *info)
	return -ENOMEM;
}

/*
 * Gather all backend feature-*
 */
static int blkfront_gather_backend_features(struct blkfront_info *info)
{
	int err;
	int barrier, flush, discard, persistent;
	unsigned int indirect_segments;

	info->feature_flush = 0;

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			"feature-barrier", "%d", &barrier,
			NULL);

	/*
	 * If there's no "feature-barrier" defined, then it means
	 * we're dealing with a very old backend which writes
	 * synchronously; nothing to do.
	 *
	 * If there are barriers, then we use flush.
	 */
	if (!err && barrier)
		info->feature_flush = REQ_FLUSH | REQ_FUA;
	/*
	 * And if there is "feature-flush-cache" use that above
	 * barriers.
	 */
	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			"feature-flush-cache", "%d", &flush,
			NULL);

	if (!err && flush)
		info->feature_flush = REQ_FLUSH;

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			"feature-discard", "%d", &discard,
			NULL);

	if (!err && discard)
		blkfront_setup_discard(info);

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			"feature-persistent", "%u", &persistent,
			NULL);
	if (err)
		info->feature_persistent = 0;
	else
		info->feature_persistent = persistent;

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-max-indirect-segments", "%u", &indirect_segments,
			    NULL);
	if (err)
		info->max_indirect_segments = 0;
	else
		info->max_indirect_segments = min(indirect_segments,
						  xen_blkif_max_segments);

	return blkfront_setup_indirect(info);
}

/*
 * Invoked when the backend is finally 'ready' (and has told produced
 * the details about the physical device - #sectors, size, etc).
@@ -1807,7 +1865,6 @@ static void blkfront_connect(struct blkfront_info *info)
	unsigned int physical_sector_size;
	unsigned int binfo;
	int err;
	int barrier, flush, discard, persistent;

	switch (info->connected) {
	case BLKIF_STATE_CONNECTED:
@@ -1864,48 +1921,7 @@ static void blkfront_connect(struct blkfront_info *info)
	if (err != 1)
		physical_sector_size = sector_size;

	info->feature_flush = 0;

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-barrier", "%d", &barrier,
			    NULL);

	/*
	 * If there's no "feature-barrier" defined, then it means
	 * we're dealing with a very old backend which writes
	 * synchronously; nothing to do.
	 *
	 * If there are barriers, then we use flush.
	 */
	if (!err && barrier)
		info->feature_flush = REQ_FLUSH | REQ_FUA;
	/*
	 * And if there is "feature-flush-cache" use that above
	 * barriers.
	 */
	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-flush-cache", "%d", &flush,
			    NULL);

	if (!err && flush)
		info->feature_flush = REQ_FLUSH;

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-discard", "%d", &discard,
			    NULL);

	if (!err && discard)
		blkfront_setup_discard(info);

	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
			    "feature-persistent", "%u", &persistent,
			    NULL);
	if (err)
		info->feature_persistent = 0;
	else
		info->feature_persistent = persistent;

	err = blkfront_setup_indirect(info);
	err = blkfront_gather_backend_features(info);
	if (err) {
		xenbus_dev_fatal(info->xbdev, err, "setup_indirect at %s",
				 info->xbdev->otherend);