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)


 mm/highmem.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff -puN mm/highmem.c~dm-bounce-buffer-fix mm/highmem.c
--- 25/mm/highmem.c~dm-bounce-buffer-fix	2003-11-21 01:20:47.000000000 -0800
+++ 25-akpm/mm/highmem.c	2003-11-21 01:20:47.000000000 -0800
@@ -285,7 +285,7 @@ static void copy_to_high_bio_irq(struct 
 	struct bio_vec *tovec, *fromvec;
 	int i;
 
-	__bio_for_each_segment(tovec, to, i, 0) {
+	bio_for_each_segment(tovec, to, i) {
 		fromvec = from->bi_io_vec + i;
 
 		/*
@@ -314,7 +314,7 @@ static void bounce_end_io(struct bio *bi
 	/*
 	 * 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;
 		if (bvec->bv_page == org_vec->bv_page)
 			continue;
@@ -437,7 +437,7 @@ static void __blk_queue_bounce(request_q
 	bio->bi_rw = (*bio_orig)->bi_rw;
 
 	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;
 
 	if (pool == page_pool) {

_