Commit 85734c47 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] dm and bounce buffer panic fix

From: Mark Haverkamp <markh@osdl.org>

About three weeks ago markw at osdl posted a mail about a panic that he
was seeing:

http://marc.theaimsgroup.com/?l=linux-kernel&m=106737176716474&w=2

I believe what is happening, is that the dm __clone_and_map function is
generating bio structures with the bi_idx field non-zero.  When
__blk_queue_bounce creates a new bio with bounce pages, it sets the bi_idx
field to 0 rather than the bi_idx of the original.  This causes trouble since
bv_page pointers will be dereferenced later that are zero.  The following
uses the original bio structure's bi_idx in the new bio structure and in
copy_to_high_bio_irq and bounce_end_io.

This has cleared up the panic when using the volume.

(acked by Joe Thornber)
parent 9907e736
...@@ -285,7 +285,7 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from) ...@@ -285,7 +285,7 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
struct bio_vec *tovec, *fromvec; struct bio_vec *tovec, *fromvec;
int i; int i;
__bio_for_each_segment(tovec, to, i, 0) { bio_for_each_segment(tovec, to, i) {
fromvec = from->bi_io_vec + i; fromvec = from->bi_io_vec + i;
/* /*
...@@ -314,7 +314,7 @@ static void bounce_end_io(struct bio *bio, mempool_t *pool) ...@@ -314,7 +314,7 @@ static void bounce_end_io(struct bio *bio, mempool_t *pool)
/* /*
* free up bounce indirect pages used * free up bounce indirect pages used
*/ */
__bio_for_each_segment(bvec, bio, i, 0) { bio_for_each_segment(bvec, bio, i) {
org_vec = bio_orig->bi_io_vec + i; org_vec = bio_orig->bi_io_vec + i;
if (bvec->bv_page == org_vec->bv_page) if (bvec->bv_page == org_vec->bv_page)
continue; continue;
...@@ -437,7 +437,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig, ...@@ -437,7 +437,7 @@ static void __blk_queue_bounce(request_queue_t *q, struct bio **bio_orig,
bio->bi_rw = (*bio_orig)->bi_rw; bio->bi_rw = (*bio_orig)->bi_rw;
bio->bi_vcnt = (*bio_orig)->bi_vcnt; bio->bi_vcnt = (*bio_orig)->bi_vcnt;
bio->bi_idx = 0; bio->bi_idx = (*bio_orig)->bi_idx;
bio->bi_size = (*bio_orig)->bi_size; bio->bi_size = (*bio_orig)->bi_size;
if (pool == page_pool) { if (pool == page_pool) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment