Skip to content

Commit

Permalink
block: convert blkdev_issue_flush() to use empty barriers
Browse files Browse the repository at this point in the history
Then we can get rid of ->issue_flush_fn() and all the driver private
implementations of that.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
  • Loading branch information
Jens Axboe committed Oct 16, 2007
1 parent bf2de6f commit fd5d806
Show file tree
Hide file tree
Showing 16 changed files with 36 additions and 329 deletions.
56 changes: 36 additions & 20 deletions block/ll_rw_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
Expand All @@ -2678,18 +2669,43 @@ 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;

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);
Expand Down
21 changes: 0 additions & 21 deletions drivers/block/ps3disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand Down
29 changes: 0 additions & 29 deletions drivers/ide/ide-disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down
28 changes: 0 additions & 28 deletions drivers/md/dm-table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
16 changes: 0 additions & 16 deletions drivers/md/dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion drivers/md/dm.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ void dm_table_postsuspend_targets(struct dm_table *t);
int dm_table_resume_targets(struct dm_table *t);
int dm_table_any_congested(struct dm_table *t, int bdi_bits);
void dm_table_unplug_all(struct dm_table *t);
int dm_table_flush_all(struct dm_table *t);

/*-----------------------------------------------------------------
* A registry of target types.
Expand Down
20 changes: 0 additions & 20 deletions drivers/md/linear.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,6 @@ static void linear_unplug(struct request_queue *q)
}
}

static int linear_issue_flush(struct request_queue *q, struct gendisk *disk,
sector_t *error_sector)
{
mddev_t *mddev = q->queuedata;
linear_conf_t *conf = mddev_to_conf(mddev);
int i, ret = 0;

for (i=0; i < mddev->raid_disks && ret == 0; i++) {
struct block_device *bdev = conf->disks[i].rdev->bdev;
struct request_queue *r_queue = bdev_get_queue(bdev);

if (!r_queue->issue_flush_fn)
ret = -EOPNOTSUPP;
else
ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
}
return ret;
}

static int linear_congested(void *data, int bits)
{
mddev_t *mddev = data;
Expand Down Expand Up @@ -279,7 +260,6 @@ static int linear_run (mddev_t *mddev)

blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
mddev->queue->issue_flush_fn = linear_issue_flush;
mddev->queue->backing_dev_info.congested_fn = linear_congested;
mddev->queue->backing_dev_info.congested_data = mddev;
return 0;
Expand Down
1 change: 0 additions & 1 deletion drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -3463,7 +3463,6 @@ static int do_md_stop(mddev_t * mddev, int mode)
mddev->pers->stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
mddev->queue->issue_flush_fn = NULL;
mddev->queue->backing_dev_info.congested_fn = NULL;
if (mddev->pers->sync_request)
sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
Expand Down
30 changes: 0 additions & 30 deletions drivers/md/multipath.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,35 +194,6 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
seq_printf (seq, "]");
}

static int multipath_issue_flush(struct request_queue *q, struct gendisk *disk,
sector_t *error_sector)
{
mddev_t *mddev = q->queuedata;
multipath_conf_t *conf = mddev_to_conf(mddev);
int i, ret = 0;

rcu_read_lock();
for (i=0; i<mddev->raid_disks && ret == 0; i++) {
mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
if (rdev && !test_bit(Faulty, &rdev->flags)) {
struct block_device *bdev = rdev->bdev;
struct request_queue *r_queue = bdev_get_queue(bdev);

if (!r_queue->issue_flush_fn)
ret = -EOPNOTSUPP;
else {
atomic_inc(&rdev->nr_pending);
rcu_read_unlock();
ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
error_sector);
rdev_dec_pending(rdev, mddev);
rcu_read_lock();
}
}
}
rcu_read_unlock();
return ret;
}
static int multipath_congested(void *data, int bits)
{
mddev_t *mddev = data;
Expand Down Expand Up @@ -527,7 +498,6 @@ static int multipath_run (mddev_t *mddev)
mddev->array_size = mddev->size;

mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->issue_flush_fn = multipath_issue_flush;
mddev->queue->backing_dev_info.congested_fn = multipath_congested;
mddev->queue->backing_dev_info.congested_data = mddev;

Expand Down
21 changes: 0 additions & 21 deletions drivers/md/raid0.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,26 +40,6 @@ static void raid0_unplug(struct request_queue *q)
}
}

static int raid0_issue_flush(struct request_queue *q, struct gendisk *disk,
sector_t *error_sector)
{
mddev_t *mddev = q->queuedata;
raid0_conf_t *conf = mddev_to_conf(mddev);
mdk_rdev_t **devlist = conf->strip_zone[0].dev;
int i, ret = 0;

for (i=0; i<mddev->raid_disks && ret == 0; i++) {
struct block_device *bdev = devlist[i]->bdev;
struct request_queue *r_queue = bdev_get_queue(bdev);

if (!r_queue->issue_flush_fn)
ret = -EOPNOTSUPP;
else
ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
}
return ret;
}

static int raid0_congested(void *data, int bits)
{
mddev_t *mddev = data;
Expand Down Expand Up @@ -250,7 +230,6 @@ static int create_strip_zones (mddev_t *mddev)

mddev->queue->unplug_fn = raid0_unplug;

mddev->queue->issue_flush_fn = raid0_issue_flush;
mddev->queue->backing_dev_info.congested_fn = raid0_congested;
mddev->queue->backing_dev_info.congested_data = mddev;

Expand Down
Loading

0 comments on commit fd5d806

Please sign in to comment.