Commit 665cc275 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] loop: copy_bio use highmem

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.)
parent c7616924
...@@ -432,13 +432,13 @@ static int loop_end_io_transfer(struct bio *bio, unsigned int bytes_done, int er ...@@ -432,13 +432,13 @@ static int loop_end_io_transfer(struct bio *bio, unsigned int bytes_done, int er
return 0; 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 *bio;
struct bio_vec *bv; struct bio_vec *bv;
int i; int i;
bio = bio_alloc(gfp_mask, rbh->bi_vcnt); bio = bio_alloc(__GFP_NOWARN, rbh->bi_vcnt);
if (!bio) if (!bio)
return NULL; return NULL;
...@@ -448,7 +448,7 @@ static struct bio *loop_copy_bio(struct bio *rbh, int gfp_mask) ...@@ -448,7 +448,7 @@ static struct bio *loop_copy_bio(struct bio *rbh, int gfp_mask)
__bio_for_each_segment(bv, rbh, i, 0) { __bio_for_each_segment(bv, rbh, i, 0) {
struct bio_vec *bbv = &bio->bi_io_vec[i]; 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) if (bbv->bv_page == NULL)
goto oom; goto oom;
...@@ -483,8 +483,7 @@ static struct bio *loop_get_buffer(struct loop_device *lo, struct bio *rbh) ...@@ -483,8 +483,7 @@ static struct bio *loop_get_buffer(struct loop_device *lo, struct bio *rbh)
int flags = current->flags; int flags = current->flags;
current->flags &= ~PF_MEMALLOC; current->flags &= ~PF_MEMALLOC;
bio = loop_copy_bio(rbh, bio = loop_copy_bio(rbh);
(GFP_ATOMIC & ~__GFP_HIGH) | __GFP_NOWARN);
current->flags = flags; current->flags = flags;
if (bio == NULL) if (bio == NULL)
blk_congestion_wait(WRITE, HZ/10); blk_congestion_wait(WRITE, HZ/10);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment