From: Milan Broz This patch implements biovec merge function for linear target. If the underlying device has merge function defined, call it. If not, keep precomputed value. Signed-off-by: Milan Broz --- drivers/md/dm-linear.c | 38 ++++++++++++++++++++++++++++++++++---- 1 files changed, 34 insertions(+), 4 deletions(-) Index: linux-2.6.21/drivers/md/dm-linear.c =================================================================== --- linux-2.6.21.orig/drivers/md/dm-linear.c 2007-05-01 17:38:30.000000000 +0100 +++ linux-2.6.21/drivers/md/dm-linear.c 2007-05-01 17:40:58.000000000 +0100 @@ -69,13 +69,18 @@ static void linear_dtr(struct dm_target kfree(lc); } -static int linear_map(struct dm_target *ti, struct bio *bio, - union map_info *map_context) +static void linear_map_bio(struct dm_target *ti, struct bio *bio) { - struct linear_c *lc = (struct linear_c *) ti->private; + struct linear_c *lc = ti->private; bio->bi_bdev = lc->dev->bdev; bio->bi_sector = lc->start + (bio->bi_sector - ti->begin); +} + +static int linear_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + linear_map_bio(ti, bio); return DM_MAPIO_REMAPPED; } @@ -114,15 +119,40 @@ static int linear_ioctl(struct dm_target return blkdev_driver_ioctl(bdev->bd_inode, &fake_file, bdev->bd_disk, cmd, arg); } +static int linear_merge(struct dm_target *ti, struct bio *bio, + struct bio_vec *biovec, int len) +{ + struct linear_c *lc = ti->private; + request_queue_t *q = bdev_get_queue(lc->dev->bdev); + + if (q->merge_bvec_fn) { + /* FIXME Yuck. Shouldn't these be merge_bvec_fn parameters? Why does the bio get passed around here at all? */ + /* FIXME Use helper function (or macro) to save this for now. */ + sector_t org_sec = bio->bi_sector; + struct block_device *org_dev = bio->bi_bdev; + + linear_map_bio(ti, bio); + + len = q->merge_bvec_fn(q, bio, biovec); + + /* FIXME Use helper function to restore this */ + bio->bi_bdev = org_dev; + bio->bi_sector = org_sec; + } + + return len; +} + static struct target_type linear_target = { .name = "linear", - .version= {1, 0, 2}, + .version= {1, 0, 3}, .module = THIS_MODULE, .ctr = linear_ctr, .dtr = linear_dtr, .map = linear_map, .status = linear_status, .ioctl = linear_ioctl, + .merge = linear_merge, }; int __init dm_linear_init(void)