aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2009-03-06 02:55:24 -0500
committerJens Axboe <jens.axboe@oracle.com>2009-03-06 02:55:24 -0500
commit59247eaea50cc68cc6ce3d3fd3855f3301b65c96 (patch)
tree76548e4273bb26568810095b14d62a4feaaf86a4
parenta3941ec101a5ec54c1e929730afeb196441a171e (diff)
block: fix missing bio back/front segment size setting in blk_recount_segments()
Commit 1e42807918d17e8c93bf14fbb74be84b141334c1 introduced a bug where we don't get front/back segment sizes in the bio in blk_recount_segments(). Fix this by tracking the back bio as well as the front bio in __blk_recalc_rq_segments(), this also cleans up the interface by getting rid of the segment size pointer passing. Tested-by: Thomas Gleixner <tglx@linutronix.de> Tested-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--block/blk-merge.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/block/blk-merge.c b/block/blk-merge.c
index a104593e70c3..5a244f05360f 100644
--- a/block/blk-merge.c
+++ b/block/blk-merge.c
@@ -39,14 +39,13 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
39} 39}
40 40
41static unsigned int __blk_recalc_rq_segments(struct request_queue *q, 41static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
42 struct bio *bio, 42 struct bio *bio)
43 unsigned int *seg_size_ptr)
44{ 43{
45 unsigned int phys_size; 44 unsigned int phys_size;
46 struct bio_vec *bv, *bvprv = NULL; 45 struct bio_vec *bv, *bvprv = NULL;
47 int cluster, i, high, highprv = 1; 46 int cluster, i, high, highprv = 1;
48 unsigned int seg_size, nr_phys_segs; 47 unsigned int seg_size, nr_phys_segs;
49 struct bio *fbio; 48 struct bio *fbio, *bbio;
50 49
51 if (!bio) 50 if (!bio)
52 return 0; 51 return 0;
@@ -87,26 +86,20 @@ new_segment:
87 seg_size = bv->bv_len; 86 seg_size = bv->bv_len;
88 highprv = high; 87 highprv = high;
89 } 88 }
89 bbio = bio;
90 } 90 }
91 91
92 if (seg_size_ptr) 92 if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size)
93 *seg_size_ptr = seg_size; 93 fbio->bi_seg_front_size = seg_size;
94 if (seg_size > bbio->bi_seg_back_size)
95 bbio->bi_seg_back_size = seg_size;
94 96
95 return nr_phys_segs; 97 return nr_phys_segs;
96} 98}
97 99
98void blk_recalc_rq_segments(struct request *rq) 100void blk_recalc_rq_segments(struct request *rq)
99{ 101{
100 unsigned int seg_size = 0, phys_segs; 102 rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio);
101
102 phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size);
103
104 if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
105 rq->bio->bi_seg_front_size = seg_size;
106 if (seg_size > rq->biotail->bi_seg_back_size)
107 rq->biotail->bi_seg_back_size = seg_size;
108
109 rq->nr_phys_segments = phys_segs;
110} 103}
111 104
112void blk_recount_segments(struct request_queue *q, struct bio *bio) 105void blk_recount_segments(struct request_queue *q, struct bio *bio)
@@ -114,7 +107,7 @@ void blk_recount_segments(struct request_queue *q, struct bio *bio)
114 struct bio *nxt = bio->bi_next; 107 struct bio *nxt = bio->bi_next;
115 108
116 bio->bi_next = NULL; 109 bio->bi_next = NULL;
117 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL); 110 bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio);
118 bio->bi_next = nxt; 111 bio->bi_next = nxt;
119 bio->bi_flags |= (1 << BIO_SEG_VALID); 112 bio->bi_flags |= (1 << BIO_SEG_VALID);
120} 113}