diff options
author | Milan Broz <mbroz@redhat.com> | 2008-07-21 07:00:37 -0400 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2008-07-21 07:00:37 -0400 |
commit | f6fccb1213ba3d661baeb2a5eee0a9701dc03e1b (patch) | |
tree | 456671e791f8a61b40e0d622591b902ca1351ae7 /drivers/md | |
parent | 92e868122edf08b9fc06b112e7e0c80ab94c1f93 (diff) |
dm: introduce merge_bvec_fn
Introduce a bvec merge function for device mapper devices
for dynamic size restrictions.
This code ensures the requested biovec lies within a single
target and then calls a target-specific function to check
against any constraints imposed by underlying devices.
Signed-off-by: Milan Broz <mbroz@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/dm.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index efe969074928..bca448e11878 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -829,6 +829,49 @@ static int __split_bio(struct mapped_device *md, struct bio *bio) | |||
829 | * CRUD END | 829 | * CRUD END |
830 | *---------------------------------------------------------------*/ | 830 | *---------------------------------------------------------------*/ |
831 | 831 | ||
832 | static int dm_merge_bvec(struct request_queue *q, | ||
833 | struct bvec_merge_data *bvm, | ||
834 | struct bio_vec *biovec) | ||
835 | { | ||
836 | struct mapped_device *md = q->queuedata; | ||
837 | struct dm_table *map = dm_get_table(md); | ||
838 | struct dm_target *ti; | ||
839 | sector_t max_sectors; | ||
840 | int max_size; | ||
841 | |||
842 | if (unlikely(!map)) | ||
843 | return 0; | ||
844 | |||
845 | ti = dm_table_find_target(map, bvm->bi_sector); | ||
846 | |||
847 | /* | ||
848 | * Find maximum amount of I/O that won't need splitting | ||
849 | */ | ||
850 | max_sectors = min(max_io_len(md, bvm->bi_sector, ti), | ||
851 | (sector_t) BIO_MAX_SECTORS); | ||
852 | max_size = (max_sectors << SECTOR_SHIFT) - bvm->bi_size; | ||
853 | if (max_size < 0) | ||
854 | max_size = 0; | ||
855 | |||
856 | /* | ||
857 | * merge_bvec_fn() returns number of bytes | ||
858 | * it can accept at this offset | ||
859 | * max is precomputed maximal io size | ||
860 | */ | ||
861 | if (max_size && ti->type->merge) | ||
862 | max_size = ti->type->merge(ti, bvm, biovec, max_size); | ||
863 | |||
864 | /* | ||
865 | * Always allow an entire first page | ||
866 | */ | ||
867 | if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT)) | ||
868 | max_size = biovec->bv_len; | ||
869 | |||
870 | dm_table_put(map); | ||
871 | |||
872 | return max_size; | ||
873 | } | ||
874 | |||
832 | /* | 875 | /* |
833 | * The request function that just remaps the bio built up by | 876 | * The request function that just remaps the bio built up by |
834 | * dm_merge_bvec. | 877 | * dm_merge_bvec. |
@@ -1032,6 +1075,7 @@ static struct mapped_device *alloc_dev(int minor) | |||
1032 | blk_queue_make_request(md->queue, dm_request); | 1075 | blk_queue_make_request(md->queue, dm_request); |
1033 | blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); | 1076 | blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); |
1034 | md->queue->unplug_fn = dm_unplug_all; | 1077 | md->queue->unplug_fn = dm_unplug_all; |
1078 | blk_queue_merge_bvec(md->queue, dm_merge_bvec); | ||
1035 | 1079 | ||
1036 | md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); | 1080 | md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); |
1037 | if (!md->io_pool) | 1081 | if (!md->io_pool) |