Commit 711daf00 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] writeback memory allocation robustness

- If we're PF_MEMALLOC and BIO allocation failed, fall back to try
  to allocate a smaller BIO (from a different mempool)

- When writepages() gets confused, call a_ops->writepage()
  instead of going directly to block_write_full_page().  It
  gives the fs more flexibility, and XFS may want this.
parent f8ca858c
...@@ -96,6 +96,12 @@ mpage_alloc(struct block_device *bdev, ...@@ -96,6 +96,12 @@ mpage_alloc(struct block_device *bdev,
struct bio *bio; struct bio *bio;
bio = bio_alloc(gfp_flags, nr_vecs); bio = bio_alloc(gfp_flags, nr_vecs);
if (bio == NULL && (current->flags & PF_MEMALLOC)) {
while (!bio && (nr_vecs /= 2))
bio = bio_alloc(gfp_flags, nr_vecs);
}
if (bio) { if (bio) {
bio->bi_bdev = bdev; bio->bi_bdev = bdev;
bio->bi_vcnt = nr_vecs; bio->bi_vcnt = nr_vecs;
...@@ -301,13 +307,13 @@ EXPORT_SYMBOL(mpage_readpage); ...@@ -301,13 +307,13 @@ EXPORT_SYMBOL(mpage_readpage);
* If the page has no buffers (preferred) then the page is mapped here. * If the page has no buffers (preferred) then the page is mapped here.
* *
* If all blocks are found to be contiguous then the page can go into the * If all blocks are found to be contiguous then the page can go into the
* BIO. Otherwise fall back to block_write_full_page(). * BIO. Otherwise fall back to the mapping's writepage().
* *
* FIXME: This code wants an estimate of how many pages are still to be * FIXME: This code wants an estimate of how many pages are still to be
* written, so it can intelligently allocate a suitably-sized BIO. For now, * written, so it can intelligently allocate a suitably-sized BIO. For now,
* just allocate full-size (16-page) BIOs. * just allocate full-size (16-page) BIOs.
*/ */
static /* inline */ struct bio * static inline struct bio *
mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block, mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
sector_t *last_block_in_bio, int *ret) sector_t *last_block_in_bio, int *ret)
{ {
...@@ -464,7 +470,7 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block, ...@@ -464,7 +470,7 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
confused: confused:
if (bio) if (bio)
bio = mpage_bio_submit(WRITE, bio); bio = mpage_bio_submit(WRITE, bio);
*ret = block_write_full_page(page, get_block); *ret = page->mapping->a_ops->writepage(page);
out: out:
return bio; return bio;
} }
......
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