iomap: Handle memory allocation failure in readahead
bio_alloc() can fail when we use GFP_NORETRY. If it does, allocate a bio large enough for a single page like mpage_readpages() does. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
committed by
Darrick J. Wong
parent
d9973ce2fe
commit
457df33e03
@@ -302,6 +302,7 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
|
|||||||
|
|
||||||
if (!ctx->bio || !is_contig || bio_full(ctx->bio, plen)) {
|
if (!ctx->bio || !is_contig || bio_full(ctx->bio, plen)) {
|
||||||
gfp_t gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL);
|
gfp_t gfp = mapping_gfp_constraint(page->mapping, GFP_KERNEL);
|
||||||
|
gfp_t orig_gfp = gfp;
|
||||||
int nr_vecs = (length + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
int nr_vecs = (length + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||||
|
|
||||||
if (ctx->bio)
|
if (ctx->bio)
|
||||||
@@ -310,6 +311,13 @@ iomap_readpage_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
|
|||||||
if (ctx->is_readahead) /* same as readahead_gfp_mask */
|
if (ctx->is_readahead) /* same as readahead_gfp_mask */
|
||||||
gfp |= __GFP_NORETRY | __GFP_NOWARN;
|
gfp |= __GFP_NORETRY | __GFP_NOWARN;
|
||||||
ctx->bio = bio_alloc(gfp, min(BIO_MAX_PAGES, nr_vecs));
|
ctx->bio = bio_alloc(gfp, min(BIO_MAX_PAGES, nr_vecs));
|
||||||
|
/*
|
||||||
|
* If the bio_alloc fails, try it again for a single page to
|
||||||
|
* avoid having to deal with partial page reads. This emulates
|
||||||
|
* what do_mpage_readpage does.
|
||||||
|
*/
|
||||||
|
if (!ctx->bio)
|
||||||
|
ctx->bio = bio_alloc(orig_gfp, 1);
|
||||||
ctx->bio->bi_opf = REQ_OP_READ;
|
ctx->bio->bi_opf = REQ_OP_READ;
|
||||||
if (ctx->is_readahead)
|
if (ctx->is_readahead)
|
||||||
ctx->bio->bi_opf |= REQ_RAHEAD;
|
ctx->bio->bi_opf |= REQ_RAHEAD;
|
||||||
|
|||||||
Reference in New Issue
Block a user