
From: Hugh Dickins <hugh@veritas.com>

loop_copy_bio uses one gfp_mask for bio_alloc and alloc_page calls.  The
bio_alloc obviously can't use highmem, but the alloc_page can.  Yes, the
underlying device might be unable to use highmem, and have to use one of
its bounce buffers, with an extra copy: so be it.

(Originally I did propagate the underlying device's bounce needs down to
the loop device, to avoid that possible extra copy; but let's keep this
simple, the low end doesn't have highmem and the high end can I/O it.)



 25-akpm/drivers/block/loop.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff -puN drivers/block/loop.c~loop-08-copy_bio-use-highmem drivers/block/loop.c
--- 25/drivers/block/loop.c~loop-08-copy_bio-use-highmem	Tue Jun 10 12:54:32 2003
+++ 25-akpm/drivers/block/loop.c	Tue Jun 10 12:54:32 2003
@@ -432,13 +432,13 @@ static int loop_end_io_transfer(struct b
 	return 0;
 }
 
-static struct bio *loop_copy_bio(struct bio *rbh, int gfp_mask)
+static struct bio *loop_copy_bio(struct bio *rbh)
 {
 	struct bio *bio;
 	struct bio_vec *bv;
 	int i;
 
-	bio = bio_alloc(gfp_mask, rbh->bi_vcnt);
+	bio = bio_alloc(__GFP_NOWARN, rbh->bi_vcnt);
 	if (!bio)
 		return NULL;
 
@@ -448,7 +448,7 @@ static struct bio *loop_copy_bio(struct 
 	__bio_for_each_segment(bv, rbh, i, 0) {
 		struct bio_vec *bbv = &bio->bi_io_vec[i];
 
-		bbv->bv_page = alloc_page(gfp_mask);
+		bbv->bv_page = alloc_page(__GFP_NOWARN|__GFP_HIGHMEM);
 		if (bbv->bv_page == NULL)
 			goto oom;
 
@@ -483,8 +483,7 @@ static struct bio *loop_get_buffer(struc
 		int flags = current->flags;
 
 		current->flags &= ~PF_MEMALLOC;
-		bio = loop_copy_bio(rbh,
-				    (GFP_ATOMIC & ~__GFP_HIGH) | __GFP_NOWARN);
+		bio = loop_copy_bio(rbh);
 		current->flags = flags;
 		if (bio == NULL)
 			blk_congestion_wait(WRITE, HZ/10);

_
