From: Ben Slusky <sluskyb@paranoiacs.org>

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;

_