History

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.

Martin K. Petersen committed 12 years ago

Commit 4eaf99b1 parent aae7df53 files · +39 −23Browse files

Unified · Split

3 files
  1. block/blk-integrity.c +26 −10
  2. block/blk-merge.c +3 −3
  3. include/linux/blkdev.h +10 −10
block/blk-integrity.c+26−10
@@ -186,37 +186,53 @@ int blk_integrity_compare(struct gendisk *gd1, struct gendisk *gd2) · 185 unmodified lines
186186 }
187187 EXPORT_SYMBOL(blk_integrity_compare);
188188
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)
191191 {
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+
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;
194201
195202 if (req->nr_integrity_segments + next->nr_integrity_segments >
196203 q->limits.max_integrity_segments)
197− return -1;
204+ return false;
198205
199− return 0;
206+ return true;
200207 }
201208 EXPORT_SYMBOL(blk_integrity_merge_rq);
202209
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)
205212 {
206213 int nr_integrity_segs;
207214 struct bio *next = bio->bi_next;
208215
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+
209225 bio->bi_next = NULL;
210226 nr_integrity_segs = blk_rq_count_integrity_sg(q, bio);
211227 bio->bi_next = next;
212228
213229 if (req->nr_integrity_segments + nr_integrity_segs >
214230 q->limits.max_integrity_segments)
215− return -1;
231+ return false;
216232
217233 req->nr_integrity_segments += nr_integrity_segs;
218234
219− return 0;
235+ return true;
220236 }
221237 EXPORT_SYMBOL(blk_integrity_merge_bio);
222238
block/blk-merge.c+3−3
@@ -313,7 +313,7 @@ static inline int ll_new_hw_segment(struct request_queue *q, · 312 unmodified lines
313313 if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q))
314314 goto no_merge;
315315
316− if (bio_integrity(bio) && blk_integrity_merge_bio(q, req, bio))
316+ if (blk_integrity_merge_bio(q, req, bio) == false)
317317 goto no_merge;
318318
319319 /*
@@ -410,7 +410,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, · 90 unmodified lines
410410 if (total_phys_segments > queue_max_segments(q))
411411 return 0;
412412
413− if (blk_integrity_rq(req) && blk_integrity_merge_rq(q, req, next))
413+ if (blk_integrity_merge_rq(q, req, next) == false)
414414 return 0;
415415
416416 /* Merge is OK... */
@@ -590,7 +590,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) · 173 unmodified lines
590590 return false;
591591
592592 /* 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)
594594 return false;
595595
596596 /* must be using the same buffer */
include/linux/blkdev.h+10−10
@@ -1497,10 +1497,10 @@ extern int blk_integrity_compare(struct gendisk *, struct gendisk *); · 1496 unmodified lines
14971497 extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,
14981498 struct scatterlist *);
14991499 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 *);
15041504
15051505 static inline
15061506 struct blk_integrity *bdev_get_integrity(struct block_device *bdev)
@@ -1580,15 +1580,15 @@ static inline unsigned short queue_max_integrity_segments(struct request_queue * · 73 unmodified lines
15801580 {
15811581 return 0;
15821582 }
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)
15861586 {
15871587 return 0;
15881588 }
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)
15921592 {
15931593 return 0;
15941594 }