From: Ben Slusky When reading from a loop device there's no reason why the encrypted and plaintext data can't occupy the same space. This will obviate the need to recycle read request bio's. Fairly trivial in and of itself. drivers/block/loop.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff -puN drivers/block/loop.c~loop-bio-clone drivers/block/loop.c --- 25/drivers/block/loop.c~loop-bio-clone 2003-12-29 22:32:40.000000000 -0800 +++ 25-akpm/drivers/block/loop.c 2003-12-29 22:33:59.000000000 -0800 @@ -367,8 +367,9 @@ static void loop_put_buffer(struct bio * struct bio_vec *bv; int i; - bio_for_each_segment(bv, bio, i) - __free_page(bv->bv_page); + if (!bio_flagged(bio, BIO_CLONED)) + bio_for_each_segment(bv, bio, i) + __free_page(bv->bv_page); bio_put(bio); } @@ -442,6 +443,11 @@ static struct bio *loop_copy_bio(struct struct bio_vec *bv; int i; + if (bio_rw(rbh) != WRITE) { + bio = bio_clone(rbh, __GFP_NOWARN); + return bio; + } + bio = bio_alloc(__GFP_NOWARN, rbh->bi_vcnt); if (!bio) return NULL; @@ -463,6 +469,7 @@ static struct bio *loop_copy_bio(struct bio->bi_idx = rbh->bi_idx; bio->bi_vcnt = rbh->bi_vcnt; bio->bi_size = rbh->bi_size; + bio->bi_rw = rbh->bi_rw; return bio; @@ -499,7 +506,6 @@ static struct bio *loop_get_buffer(struc bio->bi_end_io = loop_end_io_transfer; bio->bi_private = rbh; bio->bi_sector = rbh->bi_sector + (lo->lo_offset >> 9); - bio->bi_rw = rbh->bi_rw; bio->bi_bdev = lo->lo_device; return bio; _