@@ -32,24 +32,37 @@ static struct kmem_cache *integrity_cachep;
3232
3333/**
3434 * blk_rq_count_integrity_sg - Count number of integrity scatterlist elements
35- * @rq: request with integrity metadata attached
35+ * @q: request queue
36+ * @bio: bio with integrity metadata attached
3637 *
3738 * Description: Returns the number of elements required in a
38- * scatterlist corresponding to the integrity metadata in a request .
39+ * scatterlist corresponding to the integrity metadata in a bio .
3940 */
40- int blk_rq_count_integrity_sg (struct request * rq )
41+ int blk_rq_count_integrity_sg (struct request_queue * q , struct bio * bio )
4142{
42- struct bio_vec * iv , * ivprv ;
43- struct req_iterator iter ;
44- unsigned int segments ;
43+ struct bio_vec * iv , * ivprv = NULL ;
44+ unsigned int segments = 0 ;
45+ unsigned int seg_size = 0 ;
46+ unsigned int i = 0 ;
4547
46- ivprv = NULL ;
47- segments = 0 ;
48+ bio_for_each_integrity_vec (iv , bio , i ) {
4849
49- rq_for_each_integrity_segment (iv , rq , iter ) {
50+ if (ivprv ) {
51+ if (!BIOVEC_PHYS_MERGEABLE (ivprv , iv ))
52+ goto new_segment ;
53+
54+ if (!BIOVEC_SEG_BOUNDARY (q , ivprv , iv ))
55+ goto new_segment ;
56+
57+ if (seg_size + iv -> bv_len > queue_max_segment_size (q ))
58+ goto new_segment ;
5059
51- if (!ivprv || !BIOVEC_PHYS_MERGEABLE (ivprv , iv ))
60+ seg_size += iv -> bv_len ;
61+ } else {
62+ new_segment :
5263 segments ++ ;
64+ seg_size = iv -> bv_len ;
65+ }
5366
5467 ivprv = iv ;
5568 }
@@ -60,30 +73,34 @@ EXPORT_SYMBOL(blk_rq_count_integrity_sg);
6073
6174/**
6275 * blk_rq_map_integrity_sg - Map integrity metadata into a scatterlist
63- * @rq: request with integrity metadata attached
76+ * @q: request queue
77+ * @bio: bio with integrity metadata attached
6478 * @sglist: target scatterlist
6579 *
6680 * Description: Map the integrity vectors in request into a
6781 * scatterlist. The scatterlist must be big enough to hold all
6882 * elements. I.e. sized using blk_rq_count_integrity_sg().
6983 */
70- int blk_rq_map_integrity_sg (struct request * rq , struct scatterlist * sglist )
84+ int blk_rq_map_integrity_sg (struct request_queue * q , struct bio * bio ,
85+ struct scatterlist * sglist )
7186{
72- struct bio_vec * iv , * ivprv ;
73- struct req_iterator iter ;
74- struct scatterlist * sg ;
75- unsigned int segments ;
87+ struct bio_vec * iv , * ivprv = NULL ;
88+ struct scatterlist * sg = NULL ;
89+ unsigned int segments = 0 ;
90+ unsigned int i = 0 ;
7691
77- ivprv = NULL ;
78- sg = NULL ;
79- segments = 0 ;
80-
81- rq_for_each_integrity_segment (iv , rq , iter ) {
92+ bio_for_each_integrity_vec (iv , bio , i ) {
8293
8394 if (ivprv ) {
8495 if (!BIOVEC_PHYS_MERGEABLE (ivprv , iv ))
8596 goto new_segment ;
8697
98+ if (!BIOVEC_SEG_BOUNDARY (q , ivprv , iv ))
99+ goto new_segment ;
100+
101+ if (sg -> length + iv -> bv_len > queue_max_segment_size (q ))
102+ goto new_segment ;
103+
87104 sg -> length += iv -> bv_len ;
88105 } else {
89106new_segment :
@@ -162,6 +179,40 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2)
162179}
163180EXPORT_SYMBOL (blk_integrity_compare );
164181
182+ int blk_integrity_merge_rq (struct request_queue * q , struct request * req ,
183+ struct request * next )
184+ {
185+ if (blk_integrity_rq (req ) != blk_integrity_rq (next ))
186+ return -1 ;
187+
188+ if (req -> nr_integrity_segments + next -> nr_integrity_segments >
189+ q -> limits .max_integrity_segments )
190+ return -1 ;
191+
192+ return 0 ;
193+ }
194+ EXPORT_SYMBOL (blk_integrity_merge_rq );
195+
196+ int blk_integrity_merge_bio (struct request_queue * q , struct request * req ,
197+ struct bio * bio )
198+ {
199+ int nr_integrity_segs ;
200+ struct bio * next = bio -> bi_next ;
201+
202+ bio -> bi_next = NULL ;
203+ nr_integrity_segs = blk_rq_count_integrity_sg (q , bio );
204+ bio -> bi_next = next ;
205+
206+ if (req -> nr_integrity_segments + nr_integrity_segs >
207+ q -> limits .max_integrity_segments )
208+ return -1 ;
209+
210+ req -> nr_integrity_segments += nr_integrity_segs ;
211+
212+ return 0 ;
213+ }
214+ EXPORT_SYMBOL (blk_integrity_merge_bio );
215+
165216struct integrity_sysfs_entry {
166217 struct attribute attr ;
167218 ssize_t (* show )(struct blk_integrity * , char * );
0 commit comments