diff options
author | NeilBrown <neilb@suse.de> | 2014-12-15 12:56:57 +1100 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2015-02-04 08:35:52 +1100 |
commit | 64590f45ddc7147fa1968147a1f5b5c436b728fe (patch) | |
tree | c33e8ce09d739bac929e8ca943a253cb03cafd12 /drivers/md/linear.c | |
parent | 5c675f83c68fbdf9c0e103c1090b06be747fa62c (diff) |
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/linear.c')
-rw-r--r-- | drivers/md/linear.c | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 05108510d9cd..4c2a92ce2b0b 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -60,11 +60,10 @@ static inline struct dev_info *which_dev(struct mddev *mddev, sector_t sector) * * Return amount of bytes we can take at this offset */ -static int linear_mergeable_bvec(struct request_queue *q, +static int linear_mergeable_bvec(struct mddev *mddev, struct bvec_merge_data *bvm, struct bio_vec *biovec) { - struct mddev *mddev = q->queuedata; struct dev_info *dev0; unsigned long maxsectors, bio_sectors = bvm->bi_size >> 9; sector_t sector = bvm->bi_sector + get_start_sect(bvm->bi_bdev); @@ -213,8 +212,6 @@ static int linear_run (struct mddev *mddev) mddev->private = conf; md_set_array_sectors(mddev, linear_size(mddev, 0, 0)); - blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); - ret = md_integrity_register(mddev); if (ret) { kfree(conf); @@ -361,6 +358,7 @@ static struct md_personality linear_personality = .hot_add_disk = linear_add, .size = linear_size, .congested = linear_congested, + .mergeable_bvec = linear_mergeable_bvec, }; static int __init linear_init (void) |