diff options
author | Christoph Hellwig <hch@lst.de> | 2019-06-26 09:49:21 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-06-29 11:47:31 -0400 |
commit | d241a95f3514a5eb544dfd8d9d141ffd1c89b707 (patch) | |
tree | 4e0545aab26f747bbe890cc9756dff3d276a2de6 /block | |
parent | b2d0d99135ad145667765cbd27f148c1a4cd50d1 (diff) |
block: optionally mark pages dirty in bio_release_pages
A lot of callers of bio_release_pages also want to mark the released
pages as dirty. Add a mark_dirty parameter to avoid a second
relatively expensive bio_for_each_segment_all loop.
Reviewed-by: Minwoo Im <minwoo.im.dev@gmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block')
-rw-r--r-- | block/bio.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/block/bio.c b/block/bio.c index b35356c6093b..8a7b315630ce 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -845,7 +845,7 @@ static void bio_get_pages(struct bio *bio) | |||
845 | get_page(bvec->bv_page); | 845 | get_page(bvec->bv_page); |
846 | } | 846 | } |
847 | 847 | ||
848 | void bio_release_pages(struct bio *bio) | 848 | void bio_release_pages(struct bio *bio, bool mark_dirty) |
849 | { | 849 | { |
850 | struct bvec_iter_all iter_all; | 850 | struct bvec_iter_all iter_all; |
851 | struct bio_vec *bvec; | 851 | struct bio_vec *bvec; |
@@ -853,8 +853,11 @@ void bio_release_pages(struct bio *bio) | |||
853 | if (bio_flagged(bio, BIO_NO_PAGE_REF)) | 853 | if (bio_flagged(bio, BIO_NO_PAGE_REF)) |
854 | return; | 854 | return; |
855 | 855 | ||
856 | bio_for_each_segment_all(bvec, bio, iter_all) | 856 | bio_for_each_segment_all(bvec, bio, iter_all) { |
857 | if (mark_dirty && !PageCompound(bvec->bv_page)) | ||
858 | set_page_dirty_lock(bvec->bv_page); | ||
857 | put_page(bvec->bv_page); | 859 | put_page(bvec->bv_page); |
860 | } | ||
858 | } | 861 | } |
859 | 862 | ||
860 | static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter) | 863 | static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter) |
@@ -1683,8 +1686,7 @@ static void bio_dirty_fn(struct work_struct *work) | |||
1683 | while ((bio = next) != NULL) { | 1686 | while ((bio = next) != NULL) { |
1684 | next = bio->bi_private; | 1687 | next = bio->bi_private; |
1685 | 1688 | ||
1686 | bio_set_pages_dirty(bio); | 1689 | bio_release_pages(bio, true); |
1687 | bio_release_pages(bio); | ||
1688 | bio_put(bio); | 1690 | bio_put(bio); |
1689 | } | 1691 | } |
1690 | } | 1692 | } |
@@ -1700,7 +1702,7 @@ void bio_check_pages_dirty(struct bio *bio) | |||
1700 | goto defer; | 1702 | goto defer; |
1701 | } | 1703 | } |
1702 | 1704 | ||
1703 | bio_release_pages(bio); | 1705 | bio_release_pages(bio, false); |
1704 | bio_put(bio); | 1706 | bio_put(bio); |
1705 | return; | 1707 | return; |
1706 | defer: | 1708 | defer: |