diff options
author | Kent Overstreet <koverstreet@google.com> | 2012-09-10 14:03:28 -0700 |
---|---|---|
committer | Kent Overstreet <koverstreet@google.com> | 2013-03-23 14:26:31 -0700 |
commit | a07876064a0b73ab5ef1ebcf14b1cf0231c07858 (patch) | |
tree | 74a0567401bcdb60f5a8e65c76d5a3a21aeb548f /fs/bio.c | |
parent | cb34e057ad22a1c2c6f2cb6cd1cbd05cc2f28f28 (diff) | |
download | lwn-a07876064a0b73ab5ef1ebcf14b1cf0231c07858.tar.gz lwn-a07876064a0b73ab5ef1ebcf14b1cf0231c07858.zip |
block: Add bio_alloc_pages()
More utility code to replace stuff that's getting open coded.
Signed-off-by: Kent Overstreet <koverstreet@google.com>
CC: Jens Axboe <axboe@kernel.dk>
CC: NeilBrown <neilb@suse.de>
Diffstat (limited to 'fs/bio.c')
-rw-r--r-- | fs/bio.c | 28 |
1 files changed, 28 insertions, 0 deletions
@@ -830,6 +830,34 @@ void bio_advance(struct bio *bio, unsigned bytes) EXPORT_SYMBOL(bio_advance); /** + * bio_alloc_pages - allocates a single page for each bvec in a bio + * @bio: bio to allocate pages for + * @gfp_mask: flags for allocation + * + * Allocates pages up to @bio->bi_vcnt. + * + * Returns 0 on success, -ENOMEM on failure. On failure, any allocated pages are + * freed. + */ +int bio_alloc_pages(struct bio *bio, gfp_t gfp_mask) +{ + int i; + struct bio_vec *bv; + + bio_for_each_segment_all(bv, bio, i) { + bv->bv_page = alloc_page(gfp_mask); + if (!bv->bv_page) { + while (--bv >= bio->bi_io_vec) + __free_page(bv->bv_page); + return -ENOMEM; + } + } + + return 0; +} +EXPORT_SYMBOL(bio_alloc_pages); + +/** * bio_copy_data - copy contents of data buffers from one chain of bios to * another * @src: source bio list |