From: Milan Broz <[email-masked]>

This patch implements biovec merge function for crypt target.

If the underlying device has merge function defined, call it.
If not, keep precomputed value.

Signed-off-by: Milan Broz <[email-masked]>
Signed-off-by: Alasdair G Kergon <[email-masked]>

---
 drivers/md/dm-crypt.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletion(-)

Index: linux-2.6.25/drivers/md/dm-crypt.c
===================================================================
--- linux-2.6.25.orig/drivers/md/dm-crypt.c	2008-04-16 12:01:45.000000000 +0100
+++ linux-2.6.25/drivers/md/dm-crypt.c	2008-04-23 14:51:34.000000000 +0100
@@ -1215,9 +1215,24 @@ error:
 	return -EINVAL;
 }
 
+static int crypt_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+		       struct bio_vec *biovec, int max_size)
+{
+	struct crypt_config *cc = ti->private;
+	struct request_queue *q = bdev_get_queue(cc->dev->bdev);
+
+	if (!q->merge_bvec_fn)
+		return max_size;
+
+	bvm->bi_bdev = cc->dev->bdev;
+	bvm->bi_sector = cc->start + bvm->bi_sector - ti->begin;
+
+	return min(max_size, q->merge_bvec_fn(q, bvm, biovec));
+}
+
 static struct target_type crypt_target = {
 	.name   = "crypt",
-	.version= {1, 5, 0},
+	.version= {1, 6, 0},
 	.module = THIS_MODULE,
 	.ctr    = crypt_ctr,
 	.dtr    = crypt_dtr,
@@ -1227,6 +1242,7 @@ static struct target_type crypt_target =
 	.preresume = crypt_preresume,
 	.resume = crypt_resume,
 	.message = crypt_message,
+	.merge  = crypt_merge,
 };
 
 static int __init dm_crypt_init(void)