Re: [PATCH 2/5] block: add support for copy offload

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 5/22/25 00:31, Keith Busch wrote:
From: Keith Busch <kbusch@xxxxxxxxxx>

Various storage protocols can support offloading block data copies.
Enhance the block layer to know about the device's copying capabilities,
introduce the new REQ_OP_COPY operation, and provide the infrastructure
to iterate, split, and merge these kinds of requests.

A copy command must provide the device with a list of source LBAs and
their lengths, and a destination LBA. The 'struct bio' type doesn't
readily have a way to describe such a thing. But a copy request doesn't
use host memory for data, so the bio's bio_vec is unused space. This
patch adds a new purpose to the bio_vec where it can provide a vector of
sectors instead of memory pages.

Signed-off-by: Keith Busch <kbusch@xxxxxxxxxx>
---
  block/bio.c               | 25 ++++++++++++++
  block/blk-core.c          |  4 +++
  block/blk-lib.c           | 47 ++++++++++++++++++++++-----
  block/blk-merge.c         | 28 +++++++++++++++-
  block/blk-sysfs.c         |  9 ++++++
  block/blk.h               | 17 +++++++++-
  include/linux/bio.h       | 20 ++++++++++++
  include/linux/blk-mq.h    |  5 +++
  include/linux/blk_types.h |  2 ++
  include/linux/blkdev.h    | 14 ++++++++
  include/linux/bvec.h      | 68 +++++++++++++++++++++++++++++++++++++--
  11 files changed, 226 insertions(+), 13 deletions(-)

diff --git a/block/bio.c b/block/bio.c
index 3c0a558c90f52..9c73a895c987b 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -1156,6 +1156,31 @@ void bio_iov_bvec_set(struct bio *bio, const struct iov_iter *iter)
  	bio_set_flag(bio, BIO_CLONED);
  }
+static int bvec_try_merge_copy_src(struct bio *bio, struct bio_vec *src)
+{
+	struct bio_vec *bv;
+
+	if (!bio->bi_vcnt)
+		return false;
+
+	bv = &bio->bi_io_vec[bio->bi_vcnt - 1];
+	if (bv->bv_sector + src->bv_sectors != src->bv_sector)
+		return false;
+
+	bv->bv_sectors += src->bv_sectors;
+	return true;
+}
+
+int bio_add_copy_src(struct bio *bio, struct bio_vec *src)
+{
+	if (bvec_try_merge_copy_src(bio, src))
+		return 0;
+	if (bio->bi_vcnt >= bio->bi_max_vecs)
+		return -EINVAL;
+	bio->bi_io_vec[bio->bi_vcnt++] = *src;
+	return 0;
+}
+
  static unsigned int get_contig_folio_len(unsigned int *num_pages,
  					 struct page **pages, unsigned int i,
  					 struct folio *folio, size_t left,
diff --git a/block/blk-core.c b/block/blk-core.c
index b862c66018f25..cb3d9879e2d65 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -837,6 +837,10 @@ void submit_bio_noacct(struct bio *bio)
  		if (!bdev_max_discard_sectors(bdev))
  			goto not_supported;
  		break;
+	case REQ_OP_COPY:
+		if (!bdev_copy_sectors(bdev))
+			goto not_supported;
+		break;
  	case REQ_OP_SECURE_ERASE:
  		if (!bdev_max_secure_erase_sectors(bdev))
  			goto not_supported;
diff --git a/block/blk-lib.c b/block/blk-lib.c
index a819ded0ed3a9..a538acbaa2cd7 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -369,14 +369,7 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector,
  }
  EXPORT_SYMBOL(blkdev_issue_secure_erase);
-/**
- * blkdev_copy - copy source sectors to a destination on the same block device
- * @dst_sector:	start sector of the destination to copy to
- * @src_sector:	start sector of the source to copy from
- * @nr_sects:	number of sectors to copy
- * @gfp:	allocation flags to use
- */
-int blkdev_copy(struct block_device *bdev, sector_t dst_sector,
+static int __blkdev_copy(struct block_device *bdev, sector_t dst_sector,
  		sector_t src_sector, sector_t nr_sects, gfp_t gfp)
  {
  	unsigned int nr_vecs = __blkdev_sectors_to_bio_pages(nr_sects);

That's a bit odd, renaming a just introduced function.
But if you must...

Otherwise looks good.

Cheers,

Hannes
--
Dr. Hannes Reinecke                  Kernel Storage Architect
hare@xxxxxxx                                +49 911 74053 688
SUSE Software Solutions GmbH, Frankenstr. 146, 90461 Nürnberg
HRB 36809 (AG Nürnberg), GF: I. Totev, A. McDonald, W. Knoblich




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux