block: fix missing bio back/front segment size setting in blk_recount_segments()

Commit 1e42807918 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>
This commit is contained in:
Jens Axboe 2009-03-06 08:55:24 +01:00
parent a3941ec101
commit 59247eaea5

View file

@ -39,14 +39,13 @@ void blk_recalc_rq_sectors(struct request *rq, int nsect)
} }
static unsigned int __blk_recalc_rq_segments(struct request_queue *q, static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
struct bio *bio, struct bio *bio)
unsigned int *seg_size_ptr)
{ {
unsigned int phys_size; unsigned int phys_size;
struct bio_vec *bv, *bvprv = NULL; struct bio_vec *bv, *bvprv = NULL;
int cluster, i, high, highprv = 1; int cluster, i, high, highprv = 1;
unsigned int seg_size, nr_phys_segs; unsigned int seg_size, nr_phys_segs;
struct bio *fbio; struct bio *fbio, *bbio;
if (!bio) if (!bio)
return 0; return 0;
@ -87,26 +86,20 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
seg_size = bv->bv_len; seg_size = bv->bv_len;
highprv = high; highprv = high;
} }
bbio = bio;
} }
if (seg_size_ptr) if (nr_phys_segs == 1 && seg_size > fbio->bi_seg_front_size)
*seg_size_ptr = seg_size; fbio->bi_seg_front_size = seg_size;
if (seg_size > bbio->bi_seg_back_size)
bbio->bi_seg_back_size = seg_size;
return nr_phys_segs; return nr_phys_segs;
} }
void blk_recalc_rq_segments(struct request *rq) void blk_recalc_rq_segments(struct request *rq)
{ {
unsigned int seg_size = 0, phys_segs; rq->nr_phys_segments = __blk_recalc_rq_segments(rq->q, rq->bio);
phys_segs = __blk_recalc_rq_segments(rq->q, rq->bio, &seg_size);
if (phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
rq->bio->bi_seg_front_size = seg_size;
if (seg_size > rq->biotail->bi_seg_back_size)
rq->biotail->bi_seg_back_size = seg_size;
rq->nr_phys_segments = phys_segs;
} }
void blk_recount_segments(struct request_queue *q, struct bio *bio) void 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)
struct bio *nxt = bio->bi_next; struct bio *nxt = bio->bi_next;
bio->bi_next = NULL; bio->bi_next = NULL;
bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio, NULL); bio->bi_phys_segments = __blk_recalc_rq_segments(q, bio);
bio->bi_next = nxt; bio->bi_next = nxt;
bio->bi_flags |= (1 << BIO_SEG_VALID); bio->bi_flags |= (1 << BIO_SEG_VALID);
} }