[PATCH 1/5] block: new sector copy api

Bart Van Assche bvanassche at acm.org
Thu May 22 12:22:22 PDT 2025


On 5/21/25 3:31 PM, Keith Busch wrote:
> +/**
> + * 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,
> +		sector_t src_sector, sector_t nr_sects, gfp_t gfp)
> +{
> +	unsigned int nr_vecs = __blkdev_sectors_to_bio_pages(nr_sects);
> +	unsigned int len = (unsigned int)nr_sects << SECTOR_SHIFT;
> +	unsigned int size = min(len, nr_vecs * PAGE_SIZE);
> +	struct bio *bio;
> +	int ret = 0;
> +	void *buf;
> +
> +	if (nr_sects > UINT_MAX >> SECTOR_SHIFT)
> +		return -EINVAL;
> +
> +	buf = kvmalloc(size, gfp);
> +	if (!buf)
> +		return -ENOMEM;
> +
> +	nr_vecs = bio_add_max_vecs(buf, size);
> +	bio = bio_alloc(bdev, nr_vecs, 0, gfp);
> +
> +	if (is_vmalloc_addr(buf))
> +		bio_add_vmalloc(bio, buf, size);
> +	else
> +		bio_add_virt_nofail(bio, buf, size);
> +
> +	while (len) {
> +		size = min(len, size);
> +
> +		bio_reset(bio, bdev, REQ_OP_READ);
> +		bio->bi_iter.bi_sector = src_sector;
> +		bio->bi_iter.bi_size = size;
> +
> +		ret = submit_bio_wait(bio);
> +		if (ret)
> +			break;
> +
> +		bio_reset(bio, bdev, REQ_OP_WRITE);
> +		bio->bi_iter.bi_sector = dst_sector;
> +		bio->bi_iter.bi_size = size;
> +
> +		ret = submit_bio_wait(bio);
> +		if (ret)
> +			break;
> +
> +		src_sector += size >> SECTOR_SHIFT;
> +		dst_sector += size >> SECTOR_SHIFT;
> +		len -= size;
> +	}
> +
> +	bio_put(bio);
> +	kvfree(buf);
> +	return ret;
> +}

Is avoiding code duplication still a goal in the Linux kernel project?
If so, should the above code be consolidated with kcopyd into a single
implementation?

Thanks,

Bart.



More information about the Linux-nvme mailing list