mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00:00
blk-integrity: use iterator for mapping sg
Modify blk_rq_map_integrity_sg to use the blk-mq mapping iterator. This produces more efficient code and converges the integrity mapping implementations to reduce future maintenance burdens. The function implementation moves from blk-integrity.c to blk-mq-dma.c in order to use the types and functions private to that file. Signed-off-by: Keith Busch <kbusch@kernel.org> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20250813153153.3260897-8-kbusch@meta.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
fec9b16dc5
commit
c16b52a0a0
@ -122,64 +122,6 @@ out:
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
|
||||
* @rq: request to map
|
||||
* @sglist: target scatterlist
|
||||
*
|
||||
* Description: Map the integrity vectors in request into a
|
||||
* scatterlist. The scatterlist must be big enough to hold all
|
||||
* elements. I.e. sized using blk_rq_count_integrity_sg() or
|
||||
* rq->nr_integrity_segments.
|
||||
*/
|
||||
int blk_rq_map_integrity_sg(struct request *rq, struct scatterlist *sglist)
|
||||
{
|
||||
struct bio_vec iv, ivprv = { NULL };
|
||||
struct request_queue *q = rq->q;
|
||||
struct scatterlist *sg = NULL;
|
||||
struct bio *bio = rq->bio;
|
||||
unsigned int segments = 0;
|
||||
struct bvec_iter iter;
|
||||
int prev = 0;
|
||||
|
||||
bio_for_each_integrity_vec(iv, bio, iter) {
|
||||
if (prev) {
|
||||
if (!biovec_phys_mergeable(q, &ivprv, &iv))
|
||||
goto new_segment;
|
||||
if (sg->length + iv.bv_len > queue_max_segment_size(q))
|
||||
goto new_segment;
|
||||
|
||||
sg->length += iv.bv_len;
|
||||
} else {
|
||||
new_segment:
|
||||
if (!sg)
|
||||
sg = sglist;
|
||||
else {
|
||||
sg_unmark_end(sg);
|
||||
sg = sg_next(sg);
|
||||
}
|
||||
|
||||
sg_set_page(sg, iv.bv_page, iv.bv_len, iv.bv_offset);
|
||||
segments++;
|
||||
}
|
||||
|
||||
prev = 1;
|
||||
ivprv = iv;
|
||||
}
|
||||
|
||||
if (sg)
|
||||
sg_mark_end(sg);
|
||||
|
||||
/*
|
||||
* Something must have been wrong if the figured number of segment
|
||||
* is bigger than number of req's physical integrity segments
|
||||
*/
|
||||
BUG_ON(segments > rq->nr_integrity_segments);
|
||||
BUG_ON(segments > queue_max_integrity_segments(q));
|
||||
return segments;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_rq_map_integrity_sg);
|
||||
|
||||
int blk_rq_integrity_map_user(struct request *rq, void __user *ubuf,
|
||||
ssize_t bytes)
|
||||
{
|
||||
|
||||
@ -379,4 +379,49 @@ bool blk_rq_integrity_dma_map_iter_next(struct request *req,
|
||||
return blk_dma_map_direct(req, dma_dev, iter, &vec);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(blk_rq_integrity_dma_map_iter_next);
|
||||
|
||||
/**
|
||||
* blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
|
||||
* @rq: request to map
|
||||
* @sglist: target scatterlist
|
||||
*
|
||||
* Description: Map the integrity vectors in request into a
|
||||
* scatterlist. The scatterlist must be big enough to hold all
|
||||
* elements. I.e. sized using blk_rq_count_integrity_sg() or
|
||||
* rq->nr_integrity_segments.
|
||||
*/
|
||||
int blk_rq_map_integrity_sg(struct request *rq, struct scatterlist *sglist)
|
||||
{
|
||||
struct request_queue *q = rq->q;
|
||||
struct scatterlist *sg = NULL;
|
||||
struct bio *bio = rq->bio;
|
||||
unsigned int segments = 0;
|
||||
struct phys_vec vec;
|
||||
|
||||
struct blk_map_iter iter = {
|
||||
.bio = bio,
|
||||
.iter = bio_integrity(bio)->bip_iter,
|
||||
.bvecs = bio_integrity(bio)->bip_vec,
|
||||
.is_integrity = true,
|
||||
};
|
||||
|
||||
while (blk_map_iter_next(rq, &iter, &vec)) {
|
||||
sg = blk_next_sg(&sg, sglist);
|
||||
sg_set_page(sg, phys_to_page(vec.paddr), vec.len,
|
||||
offset_in_page(vec.paddr));
|
||||
segments++;
|
||||
}
|
||||
|
||||
if (sg)
|
||||
sg_mark_end(sg);
|
||||
|
||||
/*
|
||||
* Something must have been wrong if the figured number of segment
|
||||
* is bigger than number of req's physical integrity segments
|
||||
*/
|
||||
BUG_ON(segments > rq->nr_integrity_segments);
|
||||
BUG_ON(segments > queue_max_integrity_segments(q));
|
||||
return segments;
|
||||
}
|
||||
EXPORT_SYMBOL(blk_rq_map_integrity_sg);
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user