block copy: use merge_bvec_fn for copies We use merge_bvec_fn to make sure that copies do not split internal boundaries of device mapper devices. There is no possibility to split a copy bio (splitting would complicate the design significantly), so we must use merge_bvec_fn to make sure that the bios have appropriate size for the device mapper stack. Signed-off-by: Mikulas Patocka --- block/blk-lib.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) Index: linux-3.16-rc5/block/blk-lib.c =================================================================== --- linux-3.16-rc5.orig/block/blk-lib.c 2014-07-15 15:27:51.000000000 +0200 +++ linux-3.16-rc5/block/blk-lib.c 2014-07-15 15:27:59.000000000 +0200 @@ -369,6 +369,31 @@ static void bio_copy_end_io(struct bio * } } +static unsigned blkdev_copy_merge(struct block_device *bdev, + struct request_queue *q, unsigned long bi_rw, + sector_t sector, unsigned n) +{ + if (!q->merge_bvec_fn) { + return n; + } else { + unsigned m; + struct bvec_merge_data bvm = { + .bi_bdev = bdev, + .bi_sector = sector, + .bi_size = 0, + .bi_rw = bi_rw, + }; + struct bio_vec vec = { + .bv_page = NULL, + .bv_len = likely(n <= UINT_MAX >> 9) ? n << 9 : UINT_MAX & ~511U, + .bv_offset = 0, + }; + m = q->merge_bvec_fn(q, &bvm, &vec); + m >>= 9; + return min(m, n); + } +} + /** * blkdev_issue_copy - queue a copy same operation * @src_bdev: source blockdev @@ -424,6 +449,18 @@ int blkdev_issue_copy(struct block_devic struct bio_copy *bc; unsigned chunk = (unsigned)min(nr_sects, (sector_t)max_copy_sectors); + chunk = blkdev_copy_merge(src_bdev, sq, READ | REQ_COPY, src_sector, chunk); + if (!chunk) { + ret = -EOPNOTSUPP; + break; + } + + chunk = blkdev_copy_merge(dst_bdev, dq, WRITE | REQ_COPY, dst_sector, chunk); + if (!chunk) { + ret = -EOPNOTSUPP; + break; + } + bc = kmalloc(sizeof(struct bio_copy), gfp_mask); if (!bc) { ret = -ENOMEM;