From: Bart Van Assche <bvanassche@acm.org>
To: Jens Axboe <axboe@kernel.dk>
Cc: linux-block@vger.kernel.org, linux-scsi@vger.kernel.org,
linux-nvme@lists.infradead.org, Christoph Hellwig <hch@lst.de>,
Nitesh Shetty <nj.shetty@samsung.com>,
Bart Van Assche <bvanassche@acm.org>,
Hannes Reinecke <hare@suse.de>, Anuj Gupta <anuj20.g@samsung.com>
Subject: [PATCH 07/12] fs, block: Add copy_file_range() support for block devices
Date: Fri, 24 Apr 2026 15:41:56 -0700 [thread overview]
Message-ID: <20260424224201.1949243-8-bvanassche@acm.org> (raw)
In-Reply-To: <20260424224201.1949243-1-bvanassche@acm.org>
From: Nitesh Shetty <nj.shetty@samsung.com>
Add copy_file_range() support for block devices. If input and output block
devices have been opened with O_DIRECT and if copy offloading is supported
use blkdev_copy_offload(). Otherwise use splice_copy_file_range().
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
Signed-off-by: Nitesh Shetty <nj.shetty@samsung.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
block/fops.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/block/fops.c b/block/fops.c
index bb6642b45937..f438503f1b77 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -19,6 +19,7 @@
#include <linux/iomap.h>
#include <linux/module.h>
#include <linux/io_uring/cmd.h>
+#include <linux/splice.h>
#include "blk.h"
static inline struct inode *bdev_file_inode(struct file *file)
@@ -861,6 +862,58 @@ static ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to)
return ret;
}
+static ssize_t blkdev_copy_file_range(struct file *file_in, loff_t pos_in,
+ struct file *file_out, loff_t pos_out,
+ size_t len, unsigned int flags)
+{
+ struct block_device *in_bdev = I_BDEV(bdev_file_inode(file_in));
+ struct block_device *out_bdev = I_BDEV(bdev_file_inode(file_out));
+ loff_t in_end, out_end;
+ int err;
+
+ if (check_add_overflow(pos_in, len, &in_end) ||
+ PAGE_ALIGN(in_end) < in_end ||
+ check_add_overflow(pos_out, len, &out_end) ||
+ PAGE_ALIGN(out_end) < out_end)
+ return -EINVAL;
+
+ /*
+ * filemap_write_and_wait_range() and filemap_invalidate_inode() expect
+ * that the 'end' argument is rounded up to the next multiple of
+ * PAGE_SIZE.
+ */
+ in_end = PAGE_ALIGN(in_end);
+ out_end = PAGE_ALIGN(out_end);
+
+ if (bdev_max_copy_sectors(in_bdev) && bdev_max_copy_sectors(out_bdev) &&
+ file_in->f_iocb_flags & file_out->f_iocb_flags & IOCB_DIRECT) {
+ struct blk_copy_seg in_seg = { .pos = pos_in, .len = len };
+ struct blk_copy_seg out_seg = { .pos = pos_out, .len = len };
+ struct blk_copy_params params = {
+ .in_bdev = in_bdev,
+ .out_bdev = out_bdev,
+ .in_nseg = 1,
+ .in_segs = &in_seg,
+ .out_nseg = 1,
+ .out_segs = &out_seg,
+ };
+ err = filemap_write_and_wait_range(file_in->f_mapping, pos_in,
+ in_end);
+ if (err)
+ return err;
+ err = filemap_invalidate_inode(bdev_file_inode(file_out),
+ /*flush=*/false,
+ pos_out, out_end);
+ if (err)
+ return err;
+ if (blkdev_copy_offload(¶ms) == 0)
+ return len;
+ /* If copy offloading fails, fall back to onloading. */
+ }
+
+ return splice_copy_file_range(file_in, pos_in, file_out, pos_out, len);
+}
+
#define BLKDEV_FALLOC_FL_SUPPORTED \
(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \
FALLOC_FL_ZERO_RANGE | FALLOC_FL_WRITE_ZEROES)
@@ -967,6 +1020,7 @@ const struct file_operations def_blk_fops = {
.fallocate = blkdev_fallocate,
.uring_cmd = blkdev_uring_cmd,
.fop_flags = FOP_BUFFER_RASYNC,
+ .copy_file_range = blkdev_copy_file_range,
};
static __init int blkdev_init(void)
next prev parent reply other threads:[~2026-04-24 22:42 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-24 22:41 [PATCH 00/12] Block storage copy offloading Bart Van Assche
2026-04-24 22:41 ` [PATCH 01/12] block: Introduce queue limits for " Bart Van Assche
2026-04-24 22:41 ` [PATCH 02/12] block: Add the REQ_OP_COPY_{SRC,DST} operations Bart Van Assche
2026-04-24 22:41 ` [PATCH 03/12] block: Introduce blkdev_copy_offload() Bart Van Assche
2026-04-24 22:41 ` [PATCH 04/12] block: Add an onloaded copy implementation Bart Van Assche
2026-04-24 22:41 ` [PATCH 05/12] block: Introduce accessor functions for copy offload bios Bart Van Assche
2026-04-24 22:41 ` [PATCH 06/12] fs/read_write: Generalize generic_copy_file_checks() Bart Van Assche
2026-04-24 22:41 ` Bart Van Assche [this message]
2026-04-24 22:41 ` [PATCH 08/12] nvme: Add copy offloading support Bart Van Assche
2026-04-24 22:41 ` [PATCH 09/12] nvmet: Support the Copy command Bart Van Assche
2026-04-24 22:41 ` [PATCH 10/12] dm: Add support for copy offloading Bart Van Assche
2026-04-24 22:42 ` [PATCH 11/12] dm-linear: Enable " Bart Van Assche
2026-04-24 22:42 ` [PATCH 12/12] null_blk: Add support for REQ_OP_COPY_* Bart Van Assche
2026-05-22 12:00 ` [PATCH 00/12] Block storage copy offloading Shin'ichiro Kawasaki
2026-05-22 16:22 ` Bart Van Assche
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260424224201.1949243-8-bvanassche@acm.org \
--to=bvanassche@acm.org \
--cc=anuj20.g@samsung.com \
--cc=axboe@kernel.dk \
--cc=hare@suse.de \
--cc=hch@lst.de \
--cc=linux-block@vger.kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=linux-scsi@vger.kernel.org \
--cc=nj.shetty@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.