diff options
author | Peng Tao <bergwolf@gmail.com> | 2012-01-12 16:18:48 +0100 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-01-12 22:39:05 +0100 |
commit | 74a6eeb44ca6174d9cc93b9b8b4d58211c57bc80 (patch) | |
tree | 7aa0fc19c383f31123232103121756e48fbb84ed /fs | |
parent | pnfsblock: don't spinlock when freeing block_dev (diff) | |
download | linux-74a6eeb44ca6174d9cc93b9b8b4d58211c57bc80.tar.xz linux-74a6eeb44ca6174d9cc93b9b8b4d58211c57bc80.zip |
pnfsblock: limit bio page count
One bio can have at most BIO_MAX_PAGES pages. We should limit it bec otherwise
bio_alloc will fail when there are many pages in one read/write_pagelist.
Cc: <stable@vger.kernel.org> #3.1+
Signed-off-by: Peng Tao <peng_tao@emc.com>
Signed-off-by: Benny Halevy <bhalevy@tonian.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/blocklayout/blocklayout.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c index 6d39e9ab1e64..baf0bf2acbd4 100644 --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -146,14 +146,19 @@ static struct bio *bl_alloc_init_bio(int npg, sector_t isect, { struct bio *bio; + npg = min(npg, BIO_MAX_PAGES); bio = bio_alloc(GFP_NOIO, npg); - if (!bio) - return NULL; + if (!bio && (current->flags & PF_MEMALLOC)) { + while (!bio && (npg /= 2)) + bio = bio_alloc(GFP_NOIO, npg); + } - bio->bi_sector = isect - be->be_f_offset + be->be_v_offset; - bio->bi_bdev = be->be_mdev; - bio->bi_end_io = end_io; - bio->bi_private = par; + if (bio) { + bio->bi_sector = isect - be->be_f_offset + be->be_v_offset; + bio->bi_bdev = be->be_mdev; + bio->bi_end_io = end_io; + bio->bi_private = par; + } return bio; } |