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
  • Loading branch information
ixhamza committed Jul 17, 2024
1 parent 6520fc6 commit cf57b7b
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 7 deletions.
7 changes: 5 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 @@ -228,7 +229,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 @@ -238,7 +239,7 @@ 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)
return -EOPNOTSUPP;

ret = blkdev_copy_sanity_check(bdev, pos_in, bdev, pos_out, len);
Expand Down Expand Up @@ -270,6 +271,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
4 changes: 2 additions & 2 deletions block/fops.c
Original file line number Diff line number Diff line change
Expand Up @@ -743,11 +743,11 @@ 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 (/*(in_bdev == out_bdev) &&*/ 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);
NULL, NULL, GFP_KERNEL, out_bdev);
if (copied < 0)
copied = 0;
} else {
Expand Down
7 changes: 4 additions & 3 deletions include/linux/blkdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -1059,7 +1059,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 @@ -1234,8 +1235,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 cf57b7b

Please sign in to comment.