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

Commit fd5d8062 authored by Jens Axboe's avatar Jens Axboe
Browse files

block: convert blkdev_issue_flush() to use empty barriers



Then we can get rid of ->issue_flush_fn() and all the driver private
implementations of that.

Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent bf2de6f5
Loading
Loading
Loading
Loading
+36 −20
Original line number Diff line number Diff line
@@ -304,23 +304,6 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered,

EXPORT_SYMBOL(blk_queue_ordered);

/**
 * blk_queue_issue_flush_fn - set function for issuing a flush
 * @q:     the request queue
 * @iff:   the function to be called issuing the flush
 *
 * Description:
 *   If a driver supports issuing a flush command, the support is notified
 *   to the block layer by defining it through this call.
 *
 **/
void blk_queue_issue_flush_fn(struct request_queue *q, issue_flush_fn *iff)
{
	q->issue_flush_fn = iff;
}

EXPORT_SYMBOL(blk_queue_issue_flush_fn);

/*
 * Cache flushing for ordered writes handling
 */
@@ -2666,6 +2649,14 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,

EXPORT_SYMBOL(blk_execute_rq);

static void bio_end_empty_barrier(struct bio *bio, int err)
{
	if (err)
		clear_bit(BIO_UPTODATE, &bio->bi_flags);

	complete(bio->bi_private);
}

/**
 * blkdev_issue_flush - queue a flush
 * @bdev:	blockdev to issue flush for
@@ -2678,7 +2669,10 @@ EXPORT_SYMBOL(blk_execute_rq);
 */
int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
{
	DECLARE_COMPLETION_ONSTACK(wait);
	struct request_queue *q;
	struct bio *bio;
	int ret;

	if (bdev->bd_disk == NULL)
		return -ENXIO;
@@ -2686,10 +2680,32 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
	q = bdev_get_queue(bdev);
	if (!q)
		return -ENXIO;
	if (!q->issue_flush_fn)
		return -EOPNOTSUPP;

	return q->issue_flush_fn(q, bdev->bd_disk, error_sector);
	bio = bio_alloc(GFP_KERNEL, 0);
	if (!bio)
		return -ENOMEM;

	bio->bi_end_io = bio_end_empty_barrier;
	bio->bi_private = &wait;
	bio->bi_bdev = bdev;
	submit_bio(1 << BIO_RW_BARRIER, bio);

	wait_for_completion(&wait);

	/*
	 * The driver must store the error location in ->bi_sector, if
	 * it supports it. For non-stacked drivers, this should be copied
	 * from rq->sector.
	 */
	if (error_sector)
		*error_sector = bio->bi_sector;

	ret = 0;
	if (!bio_flagged(bio, BIO_UPTODATE))
		ret = -EIO;

	bio_put(bio);
	return ret;
}

EXPORT_SYMBOL(blkdev_issue_flush);
+0 −21
Original line number Diff line number Diff line
@@ -414,26 +414,6 @@ static void ps3disk_prepare_flush(struct request_queue *q, struct request *req)
	req->cmd_type = REQ_TYPE_FLUSH;
}

static int ps3disk_issue_flush(struct request_queue *q, struct gendisk *gendisk,
			       sector_t *sector)
{
	struct ps3_storage_device *dev = q->queuedata;
	struct request *req;
	int res;

	dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);

	req = blk_get_request(q, WRITE, __GFP_WAIT);
	ps3disk_prepare_flush(q, req);
	res = blk_execute_rq(q, gendisk, req, 0);
	if (res)
		dev_err(&dev->sbd.core, "%s:%u: flush request failed %d\n",
			__func__, __LINE__, res);
	blk_put_request(req);
	return res;
}


static unsigned long ps3disk_mask;

static DEFINE_MUTEX(ps3disk_mask_mutex);
@@ -506,7 +486,6 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
	blk_queue_dma_alignment(queue, dev->blk_size-1);
	blk_queue_hardsect_size(queue, dev->blk_size);

	blk_queue_issue_flush_fn(queue, ps3disk_issue_flush);
	blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
			  ps3disk_prepare_flush);

+0 −29
Original line number Diff line number Diff line
@@ -716,32 +716,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
	rq->buffer = rq->cmd;
}

static int idedisk_issue_flush(struct request_queue *q, struct gendisk *disk,
			       sector_t *error_sector)
{
	ide_drive_t *drive = q->queuedata;
	struct request *rq;
	int ret;

	if (!drive->wcache)
		return 0;

	rq = blk_get_request(q, WRITE, __GFP_WAIT);

	idedisk_prepare_flush(q, rq);

	ret = blk_execute_rq(q, disk, rq, 0);

	/*
	 * if we failed and caller wants error offset, get it
	 */
	if (ret && error_sector)
		*error_sector = ide_get_error_location(drive, rq->cmd);

	blk_put_request(rq);
	return ret;
}

/*
 * This is tightly woven into the driver->do_special can not touch.
 * DON'T do it again until a total personality rewrite is committed.
@@ -781,7 +755,6 @@ static void update_ordered(ide_drive_t *drive)
	struct hd_driveid *id = drive->id;
	unsigned ordered = QUEUE_ORDERED_NONE;
	prepare_flush_fn *prep_fn = NULL;
	issue_flush_fn *issue_fn = NULL;

	if (drive->wcache) {
		unsigned long long capacity;
@@ -805,13 +778,11 @@ static void update_ordered(ide_drive_t *drive)
		if (barrier) {
			ordered = QUEUE_ORDERED_DRAIN_FLUSH;
			prep_fn = idedisk_prepare_flush;
			issue_fn = idedisk_issue_flush;
		}
	} else
		ordered = QUEUE_ORDERED_DRAIN;

	blk_queue_ordered(drive->queue, ordered, prep_fn);
	blk_queue_issue_flush_fn(drive->queue, issue_fn);
}

static int write_cache(ide_drive_t *drive, int arg)
+0 −28
Original line number Diff line number Diff line
@@ -999,33 +999,6 @@ void dm_table_unplug_all(struct dm_table *t)
	}
}

int dm_table_flush_all(struct dm_table *t)
{
	struct list_head *d, *devices = dm_table_get_devices(t);
	int ret = 0;
	unsigned i;

	for (i = 0; i < t->num_targets; i++)
		if (t->targets[i].type->flush)
			t->targets[i].type->flush(&t->targets[i]);

	for (d = devices->next; d != devices; d = d->next) {
		struct dm_dev *dd = list_entry(d, struct dm_dev, list);
		struct request_queue *q = bdev_get_queue(dd->bdev);
		int err;

		if (!q->issue_flush_fn)
			err = -EOPNOTSUPP;
		else
			err = q->issue_flush_fn(q, dd->bdev->bd_disk, NULL);

		if (!ret)
			ret = err;
	}

	return ret;
}

struct mapped_device *dm_table_get_md(struct dm_table *t)
{
	dm_get(t->md);
@@ -1043,4 +1016,3 @@ EXPORT_SYMBOL(dm_table_get_md);
EXPORT_SYMBOL(dm_table_put);
EXPORT_SYMBOL(dm_table_get);
EXPORT_SYMBOL(dm_table_unplug_all);
EXPORT_SYMBOL(dm_table_flush_all);
+0 −16
Original line number Diff line number Diff line
@@ -840,21 +840,6 @@ static int dm_request(struct request_queue *q, struct bio *bio)
	return 0;
}

static int dm_flush_all(struct request_queue *q, struct gendisk *disk,
			sector_t *error_sector)
{
	struct mapped_device *md = q->queuedata;
	struct dm_table *map = dm_get_table(md);
	int ret = -ENXIO;

	if (map) {
		ret = dm_table_flush_all(map);
		dm_table_put(map);
	}

	return ret;
}

static void dm_unplug_all(struct request_queue *q)
{
	struct mapped_device *md = q->queuedata;
@@ -1003,7 +988,6 @@ static struct mapped_device *alloc_dev(int minor)
	blk_queue_make_request(md->queue, dm_request);
	blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
	md->queue->unplug_fn = dm_unplug_all;
	md->queue->issue_flush_fn = dm_flush_all;

	md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache);
	if (!md->io_pool)
Loading