From: Christof Schmitt on
From: Christof Schmitt <christof.schmitt(a)de.ibm.com>

Apply the conditions used in __blk_recalc_rq_segments also to
integrity data: Adhere to the maximum segment size and the segment
boundary set by the driver. Without this change, a driver would
receive integrity data blocks that do not adhere to the limits set for
the request queue.

Signed-off-by: Christof Schmitt <christof.schmitt(a)de.ibm.com>
---
block/blk-integrity.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)

--- a/block/blk-integrity.c
+++ b/block/blk-integrity.c
@@ -41,15 +41,22 @@ int blk_rq_count_integrity_sg(struct req
{
struct bio_vec *iv, *ivprv;
struct req_iterator iter;
- unsigned int segments;
+ unsigned int segments, seg_size;

ivprv = NULL;
segments = 0;
+ seg_size = 0;

rq_for_each_integrity_segment(iv, rq, iter) {

- if (!ivprv || !BIOVEC_PHYS_MERGEABLE(ivprv, iv))
+ if (!ivprv ||
+ !BIOVEC_PHYS_MERGEABLE(ivprv, iv) ||
+ seg_size + iv->bv_len > queue_max_segment_size(rq->q) ||
+ !BIOVEC_SEG_BOUNDARY(rq->q, ivprv, iv)) {
segments++;
+ seg_size = iv->bv_len;
+ } else
+ seg_size += iv->bv_len;

ivprv = iv;
}
@@ -81,9 +88,16 @@ int blk_rq_map_integrity_sg(struct reque
rq_for_each_integrity_segment(iv, rq, iter) {

if (ivprv) {
+ if (sg->length + iv->bv_len
+ > queue_max_segment_size(rq->q))
+ goto new_segment;
+
if (!BIOVEC_PHYS_MERGEABLE(ivprv, iv))
goto new_segment;

+ if (!BIOVEC_SEG_BOUNDARY(rq->q, ivprv, iv))
+ goto new_segment;
+
sg->length += iv->bv_len;
} else {
new_segment:

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/