Skip to content

Commit

Permalink
Add support for two bdevs in blkdev_copy_offload
Browse files Browse the repository at this point in the history
Signed-off-by: Ameer Hamza <[email protected]>
  • Loading branch information
ixhamza committed Nov 21, 2024
1 parent 93910fd commit e39ea15
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
12 changes: 10 additions & 2 deletions block/blk-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct blkdev_copy_io {

/* Keeps track of single outstanding copy offload IO */
struct blkdev_copy_offload_io {
void *driver_private;
struct blkdev_copy_io *cio;
loff_t offset;
};
Expand Down Expand Up @@ -216,7 +217,7 @@ static void blkdev_copy_offload_src_endio(struct bio *bio)
ssize_t blkdev_copy_offload(struct block_device *bdev, loff_t pos_in,
loff_t pos_out, size_t len,
void (*endio)(void *, int, ssize_t),
void *private, gfp_t gfp)
void *private, gfp_t gfp, struct block_device *bdev_out)
{
struct blkdev_copy_io *cio;
struct blkdev_copy_offload_io *offload_io;
Expand All @@ -226,10 +227,15 @@ ssize_t blkdev_copy_offload(struct block_device *bdev, loff_t pos_in,
ssize_t ret;
struct blk_plug plug;

if (!max_copy_bytes)
if (!max_copy_bytes || bdev->bd_queue->mq_ops == NULL ||
bdev->bd_queue->mq_ops != bdev_out->bd_queue->mq_ops)
return -EOPNOTSUPP;

ret = blkdev_copy_sanity_check(bdev, pos_in, bdev, pos_out, len);

if (ret == 0)
ret = blkdev_copy_sanity_check(bdev_out, pos_in, bdev, pos_out, len);

if (ret)
return ret;

Expand Down Expand Up @@ -258,6 +264,8 @@ ssize_t blkdev_copy_offload(struct block_device *bdev, loff_t pos_in,
* successful copy length
*/
offload_io->offset = len - rem;
if (bdev_out)
offload_io->driver_private = bdev_out->bd_queue->queuedata;

dst_bio = bio_alloc(bdev, 0, REQ_OP_COPY_DST, gfp);
if (!dst_bio)
Expand Down
6 changes: 3 additions & 3 deletions block/fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,12 +779,12 @@ static ssize_t blkdev_copy_file_range(struct file *file_in, loff_t pos_in,
struct block_device *out_bdev = I_BDEV(bdev_file_inode(file_out));
ssize_t copied = 0;

if ((in_bdev == out_bdev) && bdev_max_copy_sectors(in_bdev) &&
if (bdev_max_copy_sectors(in_bdev) &&
(file_in->f_iocb_flags & IOCB_DIRECT) &&
(file_out->f_iocb_flags & IOCB_DIRECT)) {
copied = blkdev_copy_offload(in_bdev, pos_in, pos_out, len,
NULL, NULL, GFP_KERNEL);
if (copied < 0)
NULL, NULL, GFP_KERNEL, out_bdev);
if (copied != -EOPNOTSUPP && copied < 0)
copied = 0;
} else {
copied = splice_copy_file_range(file_in, pos_in + copied,
Expand Down
7 changes: 4 additions & 3 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,8 @@ int blkdev_issue_secure_erase(struct block_device *bdev, sector_t sector,
ssize_t blkdev_copy_offload(struct block_device *bdev, loff_t pos_in,
loff_t pos_out, size_t len,
void (*endio)(void *, int, ssize_t),
void *private, gfp_t gfp_mask);
void *private, gfp_t gfp_mask,
struct block_device *bdev_out);

#define BLKDEV_ZERO_NOUNMAP (1 << 0) /* do not free blocks */
#define BLKDEV_ZERO_NOFALLBACK (1 << 1) /* don't write explicit zeroes */
Expand Down Expand Up @@ -1297,8 +1298,8 @@ static inline unsigned int bdev_discard_granularity(struct block_device *bdev)
return bdev_get_queue(bdev)->limits.discard_granularity;
}

/* maximum copy offload length, this is set to 128MB based on current testing */
#define BLK_COPY_MAX_BYTES (1 << 27)
/* Tested till 2GB with zvol testing */
#define BLK_COPY_MAX_BYTES (1 << 31)

static inline unsigned int bdev_max_copy_sectors(struct block_device *bdev)
{
Expand Down

0 comments on commit e39ea15

Please sign in to comment.