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
186}186}
187EXPORT_SYMBOL(blk_integrity_compare);187EXPORT_SYMBOL(blk_integrity_compare);
188 188
189int blk_integrity_merge_rq(struct request_queue *q, struct request *req,189bool blk_integrity_merge_rq(struct request_queue *q, struct request *req,
190 struct request *next)190 struct request *next)
191{191{
192 if (blk_integrity_rq(req) != blk_integrity_rq(next))192 if (blk_integrity_rq(req) == 0 && blk_integrity_rq(next) == 0)
193 return -1;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;
194 201
195 if (req->nr_integrity_segments + next->nr_integrity_segments >202 if (req->nr_integrity_segments + next->nr_integrity_segments >
196 q->limits.max_integrity_segments)203 q->limits.max_integrity_segments)
197 return -1;204 return false;
198 205
199 return 0;206 return true;
200}207}
201EXPORT_SYMBOL(blk_integrity_merge_rq);208EXPORT_SYMBOL(blk_integrity_merge_rq);
202 209
203int blk_integrity_merge_bio(struct request_queue *q, struct request *req,210bool blk_integrity_merge_bio(struct request_queue *q, struct request *req,
204 struct bio *bio)211 struct bio *bio)
205{212{
206 int nr_integrity_segs;213 int nr_integrity_segs;
207 struct bio *next = bio->bi_next;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 bio->bi_next = NULL;225 bio->bi_next = NULL;
210 nr_integrity_segs = blk_rq_count_integrity_sg(q, bio);226 nr_integrity_segs = blk_rq_count_integrity_sg(q, bio);
211 bio->bi_next = next;227 bio->bi_next = next;
212 228
213 if (req->nr_integrity_segments + nr_integrity_segs >229 if (req->nr_integrity_segments + nr_integrity_segs >
214 q->limits.max_integrity_segments)230 q->limits.max_integrity_segments)
215 return -1;231 return false;
216 232
217 req->nr_integrity_segments += nr_integrity_segs;233 req->nr_integrity_segments += nr_integrity_segs;
218 234
219 return 0;235 return true;
220}236}
221EXPORT_SYMBOL(blk_integrity_merge_bio);237EXPORT_SYMBOL(blk_integrity_merge_bio);
222 238
block/blk-merge.c+3−3
@@ -313,7 +313,7 @@ static inline int ll_new_hw_segment(struct request_queue *q, · 312 unmodified lines
313 if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q))313 if (req->nr_phys_segments + nr_phys_segs > queue_max_segments(q))
314 goto no_merge;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 goto no_merge;317 goto no_merge;
318 318
319 /*319 /*
@@ -410,7 +410,7 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req, · 90 unmodified lines
410 if (total_phys_segments > queue_max_segments(q))410 if (total_phys_segments > queue_max_segments(q))
411 return 0;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 return 0;414 return 0;
415 415
416 /* Merge is OK... */416 /* Merge is OK... */
@@ -590,7 +590,7 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio) · 173 unmodified lines
590 return false;590 return false;
591 591
592 /* only merge integrity protected bio into ditto rq */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 return false;594 return false;
595 595
596 /* must be using the same buffer */596 /* 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
1497extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,1497extern int blk_rq_map_integrity_sg(struct request_queue *, struct bio *,
1498 struct scatterlist *);1498 struct scatterlist *);
1499extern int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);1499extern int blk_rq_count_integrity_sg(struct request_queue *, struct bio *);
1500extern int blk_integrity_merge_rq(struct request_queue *, struct request *,1500extern bool blk_integrity_merge_rq(struct request_queue *, struct request *,
1501 struct request *);1501 struct request *);
1502extern int blk_integrity_merge_bio(struct request_queue *, struct request *,1502extern bool blk_integrity_merge_bio(struct request_queue *, struct request *,
1503 struct bio *);1503 struct bio *);
1504 1504
1505static inline1505static inline
1506struct blk_integrity *bdev_get_integrity(struct block_device *bdev)1506struct 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
1580{1580{
1581 return 0;1581 return 0;
1582}1582}
1583static inline int blk_integrity_merge_rq(struct request_queue *rq,1583static inline bool blk_integrity_merge_rq(struct request_queue *rq,
1584 struct request *r1,1584 struct request *r1,
1585 struct request *r2)1585 struct request *r2)
1586{1586{
1587 return 0;1587 return 0;
1588}1588}
1589static inline int blk_integrity_merge_bio(struct request_queue *rq,1589static inline bool blk_integrity_merge_bio(struct request_queue *rq,
1590 struct request *r,1590 struct request *r,
1591 struct bio *b)1591 struct bio *b)
1592{1592{
1593 return 0;1593 return 0;
1594}1594}