From: Ben Slusky <sluskyb@paranoiacs.org>

Contains the bio indexing fixes that are already in the -mm patch, plus some
similarly trivial fixes in the block-backed code.  Basically the loop driver
assumes that all bio's have allocated pages starting at index 0 in the
bio_vec.  In practice this assumption works but there's no reason why it
should, and recycling bio's will ruin it completely anyway.



 drivers/block/loop.c |   26 ++++++++++++--------------
 1 files changed, 12 insertions(+), 14 deletions(-)

diff -puN drivers/block/loop.c~loop-bio-index-fix drivers/block/loop.c
--- 25/drivers/block/loop.c~loop-bio-index-fix	2003-12-29 22:31:35.000000000 -0800
+++ 25-akpm/drivers/block/loop.c	2003-12-29 22:31:35.000000000 -0800
@@ -247,12 +247,10 @@ fail:
 static int
 lo_send(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
 {
-	unsigned vecnr;
-	int ret = 0;
-
-	for (vecnr = 0; vecnr < bio->bi_vcnt; vecnr++) {
-		struct bio_vec *bvec = &bio->bi_io_vec[vecnr];
+	struct bio_vec *bvec;
+	int i, ret = 0;
 
+	bio_for_each_segment(bvec, bio, i) {
 		ret = do_lo_send(lo, bvec, bsize, pos);
 		if (ret < 0)
 			break;
@@ -318,12 +316,10 @@ do_lo_receive(struct loop_device *lo,
 static int
 lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos)
 {
-	unsigned vecnr;
-	int ret = 0;
-
-	for (vecnr = 0; vecnr < bio->bi_vcnt; vecnr++) {
-		struct bio_vec *bvec = &bio->bi_io_vec[vecnr];
+	struct bio_vec *bvec;
+	int i, ret = 0;
 
+	bio_for_each_segment(bvec, bio, i) {
 		ret = do_lo_receive(lo, bvec, bsize, pos);
 		if (ret < 0)
 			break;
@@ -353,10 +349,11 @@ static void loop_put_buffer(struct bio *
 	 * check bi_end_io, may just be a remapped bio
 	 */
 	if (bio && bio->bi_end_io == loop_end_io_transfer) {
+		struct bio_vec *bv;
 		int i;
 
-		for (i = 0; i < bio->bi_vcnt; i++)
-			__free_page(bio->bi_io_vec[i].bv_page);
+		bio_for_each_segment(bv, bio, i)
+			__free_page(bv->bv_page);
 
 		bio_put(bio);
 	}
@@ -437,7 +434,7 @@ static struct bio *loop_copy_bio(struct 
 	/*
 	 * iterate iovec list and alloc pages
 	 */
-	__bio_for_each_segment(bv, rbh, i, 0) {
+	bio_for_each_segment(bv, rbh, i) {
 		struct bio_vec *bbv = &bio->bi_io_vec[i];
 
 		bbv->bv_page = alloc_page(__GFP_NOWARN|__GFP_HIGHMEM);
@@ -448,6 +445,7 @@ static struct bio *loop_copy_bio(struct 
 		bbv->bv_offset = bv->bv_offset;
 	}
 
+	bio->bi_idx = rbh->bi_idx;
 	bio->bi_vcnt = rbh->bi_vcnt;
 	bio->bi_size = rbh->bi_size;
 
@@ -502,7 +500,7 @@ static int loop_transfer_bio(struct loop
 
 	IV = from_bio->bi_sector + (lo->lo_offset >> 9);
 
-	__bio_for_each_segment(from_bvec, from_bio, i, 0) {
+	bio_for_each_segment(from_bvec, from_bio, i) {
 		to_bvec = &to_bio->bi_io_vec[i];
 
 		kmap(from_bvec->bv_page);

_