diff options
author | Ming Lei <ming.lei@redhat.com> | 2019-03-17 18:01:07 +0800 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-04-01 12:11:30 -0600 |
commit | 5919482e222908d40279a616b1fe6400549e32b4 (patch) | |
tree | 7d1bc404915ed59a90eb7fb4e7897e46c0f26022 /block | |
parent | 5a8ce240d4d302d27a58fd34499b2404b3a8df4f (diff) | |
download | linux-5919482e222908d40279a616b1fe6400549e32b4.tar.gz linux-5919482e222908d40279a616b1fe6400549e32b4.tar.bz2 linux-5919482e222908d40279a616b1fe6400549e32b4.zip |
block: check if page is mergeable in one helper
Now the check for deciding if one page is mergeable to current bvec
becomes a bit complicated, and we need to reuse the code before
adding pc page.
So move the check in one dedicated helper.
No function change.
Cc: Omar Sandoval <osandov@fb.com>
Cc: Christoph Hellwig <hch@lst.de>
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/bio.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/block/bio.c b/block/bio.c index cbd202250a32..7ab7060a0e6c 100644 --- a/block/bio.c +++ b/block/bio.c @@ -647,6 +647,24 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs) } EXPORT_SYMBOL(bio_clone_fast); +static inline bool page_is_mergeable(const struct bio_vec *bv, + struct page *page, unsigned int len, unsigned int off, + bool same_page) +{ + phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) + + bv->bv_offset + bv->bv_len - 1; + phys_addr_t page_addr = page_to_phys(page); + + if (vec_end_addr + 1 != page_addr + off) + return false; + if (xen_domain() && !xen_biovec_phys_mergeable(bv, page)) + return false; + if (same_page && (vec_end_addr & PAGE_MASK) != page_addr) + return false; + + return true; +} + /** * bio_add_pc_page - attempt to add page to passthrough bio * @q: the target queue @@ -770,20 +788,12 @@ bool __bio_try_merge_page(struct bio *bio, struct page *page, if (bio->bi_vcnt > 0) { struct bio_vec *bv = &bio->bi_io_vec[bio->bi_vcnt - 1]; - phys_addr_t vec_end_addr = page_to_phys(bv->bv_page) + - bv->bv_offset + bv->bv_len - 1; - phys_addr_t page_addr = page_to_phys(page); - - if (vec_end_addr + 1 != page_addr + off) - return false; - if (xen_domain() && !xen_biovec_phys_mergeable(bv, page)) - return false; - if (same_page && (vec_end_addr & PAGE_MASK) != page_addr) - return false; - - bv->bv_len += len; - bio->bi_iter.bi_size += len; - return true; + + if (page_is_mergeable(bv, page, len, off, same_page)) { + bv->bv_len += len; + bio->bi_iter.bi_size += len; + return true; + } } return false; } |