Commit 4eaf99beadcefbf126fa05e66fb40fca999e09fd
Committed by
Jens Axboe
1 parent
aae7df5019
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
block: Don't merge requests if integrity flags differ
We'd occasionally merge requests with conflicting integrity flags. Introduce a merge helper which checks that the requests have compatible integrity payloads. Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Sagi Grimberg <sagig@mellanox.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Showing 3 changed files with 39 additions and 23 deletions Side-by-side Diff
block/blk-integrity.c
... | ... | @@ -186,37 +186,53 @@ |
186 | 186 | } |
187 | 187 | EXPORT_SYMBOL(blk_integrity_compare); |
188 | 188 | |
189 | -int blk_integrity_merge_rq(struct request_queue *q, struct request *req, | |
190 | - struct request *next) | |
189 | +bool blk_integrity_merge_rq(struct request_queue *q, struct request *req, | |
190 | + struct request *next) | |
191 | 191 | { |
192 | - if (blk_integrity_rq(req) != blk_integrity_rq(next)) | |
193 | - return -1; | |
192 | + if (blk_integrity_rq(req) == 0 && blk_integrity_rq(next) == 0) | |
193 | + return true; | |
194 | 194 | |
195 | + if (blk_integrity_rq(req) == 0 || blk_integrity_rq(next) == 0) | |
196 | + return false; | |
197 | + | |
198 | + if (bio_integrity(req->bio)->bip_flags != | |
199 | + bio_integrity(next->bio)->bip_flags) | |
200 | + return false; | |
201 | + | |
195 | 202 | if (req->nr_integrity_segments + next->nr_integrity_segments > |
196 | 203 | q->limits.max_integrity_segments) |
197 | - return -1; | |
204 | + return false; | |
198 | 205 | |
199 | - return 0; | |
206 | + return true; | |
200 | 207 | } |
201 | 208 | EXPORT_SYMBOL(blk_integrity_merge_rq); |
202 | 209 | |
203 | -int blk_integrity_merge_bio(struct request_queue *q, struct request *req, | |
204 | - struct bio *bio) | |
210 | +bool blk_integrity_merge_bio(struct request_queue *q, struct request *req, | |
211 | + struct bio *bio) | |
205 | 212 | { |
206 | 213 | int nr_integrity_segs; |
207 | 214 | struct bio *next = bio->bi_next; |
208 | 215 | |
216 | + if (blk_integrity_rq(req) == 0 && bio_integrity(bio) == NULL) | |
217 | + return true; | |
218 | + | |
219 | + if (blk_integrity_rq(req) == 0 || bio_integrity(bio) == NULL) | |
220 | + return false; | |
221 | + | |
222 | + if (bio_integrity(req->bio)->bip_flags != bio_integrity(bio)->bip_flags) | |
223 | + return false; | |
224 | + | |
209 | 225 | bio->bi_next = NULL; |
210 | 226 | nr_integrity_segs = blk_rq_count_integrity_sg(q, bio); |
211 | 227 | bio->bi_next = next; |
212 | 228 | |
213 | 229 | if (req->nr_integrity_segments + nr_integrity_segs > |
214 | 230 | q->limits.max_integrity_segments) |
215 | - return -1; | |
231 | + return false; | |
216 | 232 | |
217 | 233 | req->nr_integrity_segments += nr_integrity_segs; |
218 | 234 | |
219 | - return 0; | |
235 | + return true; | |
220 | 236 | } |
221 | 237 | EXPORT_SYMBOL(blk_integrity_merge_bio); |
222 | 238 |
block/blk-merge.c
... | ... | @@ -313,7 +313,7 @@ |
313 | 313 | if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q)) |
314 | 314 | goto no_merge; |
315 | 315 | |
316 | - if (bio_integrity(bio) && blk_integrity_merge_bio(q, req, bio)) | |
316 | + if (blk_integrity_merge_bio(q, req, bio) == false) | |
317 | 317 | goto no_merge; |
318 | 318 | |
319 | 319 | /* |
... | ... | @@ -410,7 +410,7 @@ |
410 | 410 | if (total_phys_segments > queue_max_segments(q)) |
411 | 411 | return 0; |
412 | 412 | |
413 | - if (blk_integrity_rq(req) && blk_integrity_merge_rq(q, req, next)) | |
413 | + if (blk_integrity_merge_rq(q, req, next) == false) | |
414 | 414 | return 0; |
415 | 415 | |
416 | 416 | /* Merge is OK... */ |
... | ... | @@ -590,7 +590,7 @@ |
590 | 590 | return false; |
591 | 591 | |
592 | 592 | /* only merge integrity protected bio into ditto rq */ |
593 | - if (bio_integrity(bio) != blk_integrity_rq(rq)) | |
593 | + if (blk_integrity_merge_bio(rq->q, rq, bio) == false) | |
594 | 594 | return false; |
595 | 595 | |
596 | 596 | /* must be using the same buffer */ |
include/linux/blkdev.h
... | ... | @@ -1497,10 +1497,10 @@ |
1497 | 1497 | extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *, |
1498 | 1498 | struct scatterlist *); |
1499 | 1499 | extern int blk_rq_count_integrity_sg(struct request_queue *, struct bio *); |
1500 | -extern int blk_integrity_merge_rq(struct request_queue *, struct request *, | |
1501 | - struct request *); | |
1502 | -extern int blk_integrity_merge_bio(struct request_queue *, struct request *, | |
1503 | - struct bio *); | |
1500 | +extern bool blk_integrity_merge_rq(struct request_queue *, struct request *, | |
1501 | + struct request *); | |
1502 | +extern bool blk_integrity_merge_bio(struct request_queue *, struct request *, | |
1503 | + struct bio *); | |
1504 | 1504 | |
1505 | 1505 | static inline |
1506 | 1506 | struct blk_integrity *bdev_get_integrity(struct block_device *bdev) |
1507 | 1507 | |
... | ... | @@ -1580,15 +1580,15 @@ |
1580 | 1580 | { |
1581 | 1581 | return 0; |
1582 | 1582 | } |
1583 | -static inline int blk_integrity_merge_rq(struct request_queue *rq, | |
1584 | - struct request *r1, | |
1585 | - struct request *r2) | |
1583 | +static inline bool blk_integrity_merge_rq(struct request_queue *rq, | |
1584 | + struct request *r1, | |
1585 | + struct request *r2) | |
1586 | 1586 | { |
1587 | 1587 | return 0; |
1588 | 1588 | } |
1589 | -static inline int blk_integrity_merge_bio(struct request_queue *rq, | |
1590 | - struct request *r, | |
1591 | - struct bio *b) | |
1589 | +static inline bool blk_integrity_merge_bio(struct request_queue *rq, | |
1590 | + struct request *r, | |
1591 | + struct bio *b) | |
1592 | 1592 | { |
1593 | 1593 | return 0; |
1594 | 1594 | } |
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a
-
mentioned in commit cb1a5a