summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorKeith Busch <kbusch@kernel.org>2024-09-13 12:17:46 -0700
committerJens Axboe <axboe@kernel.dk>2024-09-13 13:22:09 -0600
commit76c313f658d2752e8527610677164aa7094ef7a5 (patch)
treec25189dcc7f657058d8f3ef73eb31f8f8d08c572 /block
parentdb5197b554fcb8fde0182af65e8e94bec414e342 (diff)
downloadlwn-76c313f658d2752e8527610677164aa7094ef7a5.tar.gz
lwn-76c313f658d2752e8527610677164aa7094ef7a5.zip
blk-integrity: improved sg segment mapping
Make the integrity mapping more like data mapping, blk_rq_map_sg. Use the request to validate the segment count, and update the callers so they don't have to. Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Keith Busch <kbusch@kernel.org> Link: https://lore.kernel.org/r/20240913191746.2628196-1-kbusch@meta.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/blk-integrity.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 1d82b18e06f8..0a2b1c5d0ebf 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -62,19 +62,20 @@ new_segment:
*
* 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().
+ * elements. I.e. sized using blk_rq_count_integrity_sg() or
+ * rq->nr_integrity_segments.
*/
-int blk_rq_map_integrity_sg(struct request_queue *q, struct bio *bio,
- struct scatterlist *sglist)
+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;
@@ -102,6 +103,12 @@ new_segment:
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);