diff options
author | NeilBrown <neilb@suse.de> | 2014-12-15 02:56:57 +0100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2015-02-03 22:35:52 +0100 |
commit | 64590f45ddc7147fa1968147a1f5b5c436b728fe (patch) | |
tree | c33e8ce09d739bac929e8ca943a253cb03cafd12 /drivers/md/raid5.c | |
parent | md: make ->congested robust against personality changes. (diff) | |
download | linux-64590f45ddc7147fa1968147a1f5b5c436b728fe.tar.xz linux-64590f45ddc7147fa1968147a1f5b5c436b728fe.zip |
md: make merge_bvec_fn more robust in face of personality changes.
There is no locking around calls to merge_bvec_fn(), so
it is possible that calls which coincide with a level (or personality)
change could go wrong.
So create a central dispatch point for these functions and use
rcu_read_lock().
If the array is suspended, reject any merge that can be rejected.
If not, we know it is safe to call the function.
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r-- | drivers/md/raid5.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 502a908149c6..2d4a2cc85eb2 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -4170,11 +4170,10 @@ static int raid5_congested(struct mddev *mddev, int bits) /* We want read requests to align with chunks where possible, * but write requests don't need to. */ -static int raid5_mergeable_bvec(struct request_queue *q, +static int raid5_mergeable_bvec(struct mddev *mddev, struct bvec_merge_data *bvm, struct bio_vec *biovec) { - struct mddev *mddev = q->queuedata; sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); int max; unsigned int chunk_sectors = mddev->chunk_sectors; @@ -6237,8 +6236,6 @@ static int run(struct mddev *mddev) if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe) mddev->queue->backing_dev_info.ra_pages = 2 * stripe; - blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec); - chunk_size = mddev->chunk_sectors << 9; blk_queue_io_min(mddev->queue, chunk_size); blk_queue_io_opt(mddev->queue, chunk_size * @@ -7113,6 +7110,7 @@ static struct md_personality raid6_personality = .quiesce = raid5_quiesce, .takeover = raid6_takeover, .congested = raid5_congested, + .mergeable_bvec = raid5_mergeable_bvec, }; static struct md_personality raid5_personality = { @@ -7136,6 +7134,7 @@ static struct md_personality raid5_personality = .quiesce = raid5_quiesce, .takeover = raid5_takeover, .congested = raid5_congested, + .mergeable_bvec = raid5_mergeable_bvec, }; static struct md_personality raid4_personality = @@ -7160,6 +7159,7 @@ static struct md_personality raid4_personality = .quiesce = raid5_quiesce, .takeover = raid4_takeover, .congested = raid5_congested, + .mergeable_bvec = raid5_mergeable_bvec, }; static int __init raid5_init(void) |