On 07/15/2014 09:34 PM, Mikulas Patocka wrote:
This is Martin Petersen's xcopy patch
(https://git.kernel.org/cgit/linux/kernel/git/mkp/linux.git/commit/?h=xcopyid=0bdeed274e16b3038a851552188512071974eea8)
with some bug fixes, ported to the current kernel.
This patch makes it possible to use the SCSI XCOPY command.
We create a bio that has REQ_COPY flag in bi_rw and a bi_copy structure
that defines the source device. The target device is defined in the
bi_bdev and bi_iter.bi_sector.
There is a new BLKCOPY ioctl that makes it possible to use XCOPY from
userspace. The ioctl argument is a pointer to an array of four uint64_t
values.
The first value is a source byte offset, the second value is a destination
byte offset, the third value is byte length. The forth value is written by
the kernel and it represents the number of bytes that the kernel actually
copied.
Signed-off-by: Martin K. Petersen martin.peter...@oracle.com
Signed-off-by: Mikulas Patocka mpato...@redhat.com
---
Documentation/ABI/testing/sysfs-block |9 +
block/bio.c |2
block/blk-core.c |5
block/blk-lib.c | 95
block/blk-merge.c |7
block/blk-settings.c | 13 +
block/blk-sysfs.c | 10 +
block/compat_ioctl.c |1
block/ioctl.c | 49 ++
drivers/scsi/scsi.c | 57 +++
drivers/scsi/sd.c | 263
+-
drivers/scsi/sd.h |4
include/linux/bio.h |9 -
include/linux/blk_types.h | 15 +
include/linux/blkdev.h| 15 +
include/scsi/scsi_device.h|3
include/uapi/linux/fs.h |1
17 files changed, 545 insertions(+), 13 deletions(-)
Index: linux-3.16-rc5/Documentation/ABI/testing/sysfs-block
===
--- linux-3.16-rc5.orig/Documentation/ABI/testing/sysfs-block 2014-07-14
15:17:07.0 +0200
+++ linux-3.16-rc5/Documentation/ABI/testing/sysfs-block 2014-07-14
16:26:44.0 +0200
@@ -220,3 +220,12 @@ Description:
write_same_max_bytes is 0, write same is not supported
by the device.
+
+What:/sys/block/disk/queue/copy_max_bytes
+Date:January 2014
+Contact: Martin K. Petersen martin.peter...@oracle.com
+Description:
+ Devices that support copy offloading will set this value
+ to indicate the maximum buffer size in bytes that can be
+ copied in one operation. If the copy_max_bytes is 0 the
+ device does not support copy offload.
Index: linux-3.16-rc5/block/blk-core.c
===
--- linux-3.16-rc5.orig/block/blk-core.c 2014-07-14 16:26:22.0
+0200
+++ linux-3.16-rc5/block/blk-core.c 2014-07-14 16:26:44.0 +0200
@@ -1831,6 +1831,11 @@ generic_make_request_checks(struct bio *
goto end_io;
}
+ if (bio-bi_rw REQ_COPY !bdev_copy_offload(bio-bi_bdev)) {
+ err = -EOPNOTSUPP;
+ goto end_io;
+ }
+
/*
* Various block parts want %current-io_context and lazy ioc
* allocation ends up trading a lot of pain for a small amount of
Index: linux-3.16-rc5/block/blk-lib.c
===
--- linux-3.16-rc5.orig/block/blk-lib.c 2014-07-14 16:26:40.0
+0200
+++ linux-3.16-rc5/block/blk-lib.c2014-07-14 16:32:21.0 +0200
@@ -304,3 +304,98 @@ int blkdev_issue_zeroout(struct block_de
return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask);
}
EXPORT_SYMBOL(blkdev_issue_zeroout);
+
+/**
+ * blkdev_issue_copy - queue a copy same operation
+ * @src_bdev:source blockdev
+ * @src_sector: source sector
+ * @dst_bdev:destination blockdev
+ * @dst_sector: destination sector
+ * @nr_sects:number of sectors to copy
+ * @gfp_mask:memory allocation flags (for bio_alloc)
+ *
+ * Description:
+ *Copy a block range from source device to target device.
+ */
+int blkdev_issue_copy(struct block_device *src_bdev, sector_t src_sector,
+ struct block_device *dst_bdev, sector_t dst_sector,
+ unsigned int nr_sects, gfp_t gfp_mask)
+{
+ DECLARE_COMPLETION_ONSTACK(wait);
+ struct request_queue *sq = bdev_get_queue(src_bdev);
+ struct request_queue *dq = bdev_get_queue(dst_bdev);
+ unsigned int max_copy_sectors;
+ struct bio_batch bb;
+ int ret = 0;
+
+ if (!sq || !dq)
+ return -ENXIO;
+
+ max_copy_sectors = min(sq-limits.max_copy_sectors,
+