From: Ben Slusky 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); _