summaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorKeith Busch <kbusch@kernel.org>2024-09-13 11:28:48 -0700
committerJens Axboe <axboe@kernel.dk>2024-09-13 12:31:45 -0600
commitd148d7503456556859c7e4d354115215d8fb5016 (patch)
treed6c05aa23c52744ca09030fe79dea01d6892a3d3 /block
parent9c297eced59817f461be33e4c241820c5be4bcc1 (diff)
blk-integrity: properly account for segments
Both types of merging when integrity data is used are miscounting the segments: Merging two requests wasn't accounting for the new segment count, so add the "next" segment count to the first on a successful merge to ensure this value is accurate. Merging a bio into an existing request was double counting the bio's segments, even if the merge failed later on. Move the segment accounting to the end when the merge is successful. 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/20240913182854.2445457-4-kbusch@meta.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r--block/blk-integrity.c2
-rw-r--r--block/blk-merge.c4
2 files changed, 4 insertions, 2 deletions
diff --git a/block/blk-integrity.c b/block/blk-integrity.c
index 010decc892ea..afd101555d3c 100644
--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -153,8 +153,6 @@ bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
q->limits.max_integrity_segments)
return false;
- req->nr_integrity_segments += nr_integrity_segs;
-
return true;
}
diff --git a/block/blk-merge.c b/block/blk-merge.c
index 56769c4bcd79..ad763ec313b6 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -639,6 +639,9 @@ static inline int ll_new_hw_segment(struct request *req, struct bio *bio,
* counters.
*/
req->nr_phys_segments += nr_phys_segs;
+ if (bio_integrity(bio))
+ req->nr_integrity_segments += blk_rq_count_integrity_sg(req->q,
+ bio);
return 1;
no_merge:
@@ -731,6 +734,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
/* Merge is OK... */
req->nr_phys_segments = total_phys_segments;
+ req->nr_integrity_segments += next->nr_integrity_segments;
return 1;
}