summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/bio.c51
-rw-r--r--include/linux/bvec.h5
2 files changed, 25 insertions, 31 deletions
diff --git a/block/bio.c b/block/bio.c
index c2a389b1509a..d3490aeb1a7e 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -861,6 +861,26 @@ int bio_add_page(struct bio *bio, struct page *page,
861} 861}
862EXPORT_SYMBOL(bio_add_page); 862EXPORT_SYMBOL(bio_add_page);
863 863
864static void bio_get_pages(struct bio *bio)
865{
866 struct bvec_iter_all iter_all;
867 struct bio_vec *bvec;
868 int i;
869
870 bio_for_each_segment_all(bvec, bio, i, iter_all)
871 get_page(bvec->bv_page);
872}
873
874static void bio_release_pages(struct bio *bio)
875{
876 struct bvec_iter_all iter_all;
877 struct bio_vec *bvec;
878 int i;
879
880 bio_for_each_segment_all(bvec, bio, i, iter_all)
881 put_page(bvec->bv_page);
882}
883
864static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter) 884static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter)
865{ 885{
866 const struct bio_vec *bv = iter->bvec; 886 const struct bio_vec *bv = iter->bvec;
@@ -875,15 +895,6 @@ static int __bio_iov_bvec_add_pages(struct bio *bio, struct iov_iter *iter)
875 bv->bv_offset + iter->iov_offset); 895 bv->bv_offset + iter->iov_offset);
876 if (unlikely(size != len)) 896 if (unlikely(size != len))
877 return -EINVAL; 897 return -EINVAL;
878
879 if (!bio_flagged(bio, BIO_NO_PAGE_REF)) {
880 struct page *page;
881 int i;
882
883 mp_bvec_for_each_page(page, bv, i)
884 get_page(page);
885 }
886
887 iov_iter_advance(iter, size); 898 iov_iter_advance(iter, size);
888 return 0; 899 return 0;
889} 900}
@@ -963,13 +974,6 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
963 if (WARN_ON_ONCE(bio->bi_vcnt)) 974 if (WARN_ON_ONCE(bio->bi_vcnt))
964 return -EINVAL; 975 return -EINVAL;
965 976
966 /*
967 * If this is a BVEC iter, then the pages are kernel pages. Don't
968 * release them on IO completion, if the caller asked us to.
969 */
970 if (is_bvec && iov_iter_bvec_no_ref(iter))
971 bio_set_flag(bio, BIO_NO_PAGE_REF);
972
973 do { 977 do {
974 if (is_bvec) 978 if (is_bvec)
975 ret = __bio_iov_bvec_add_pages(bio, iter); 979 ret = __bio_iov_bvec_add_pages(bio, iter);
@@ -977,6 +981,11 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter)
977 ret = __bio_iov_iter_get_pages(bio, iter); 981 ret = __bio_iov_iter_get_pages(bio, iter);
978 } while (!ret && iov_iter_count(iter) && !bio_full(bio)); 982 } while (!ret && iov_iter_count(iter) && !bio_full(bio));
979 983
984 if (iov_iter_bvec_no_ref(iter))
985 bio_set_flag(bio, BIO_NO_PAGE_REF);
986 else
987 bio_get_pages(bio);
988
980 return bio->bi_vcnt ? 0 : ret; 989 return bio->bi_vcnt ? 0 : ret;
981} 990}
982 991
@@ -1670,16 +1679,6 @@ void bio_set_pages_dirty(struct bio *bio)
1670 } 1679 }
1671} 1680}
1672 1681
1673static void bio_release_pages(struct bio *bio)
1674{
1675 struct bio_vec *bvec;
1676 int i;
1677 struct bvec_iter_all iter_all;
1678
1679 bio_for_each_segment_all(bvec, bio, i, iter_all)
1680 put_page(bvec->bv_page);
1681}
1682
1683/* 1682/*
1684 * bio_check_pages_dirty() will check that all the BIO's pages are still dirty. 1683 * bio_check_pages_dirty() will check that all the BIO's pages are still dirty.
1685 * If they are, then fine. If, however, some pages are clean then they must 1684 * If they are, then fine. If, however, some pages are clean then they must
diff --git a/include/linux/bvec.h b/include/linux/bvec.h
index f6275c4da13a..307bbda62b7b 100644
--- a/include/linux/bvec.h
+++ b/include/linux/bvec.h
@@ -189,9 +189,4 @@ static inline void mp_bvec_last_segment(const struct bio_vec *bvec,
189 } 189 }
190} 190}
191 191
192#define mp_bvec_for_each_page(pg, bv, i) \
193 for (i = (bv)->bv_offset / PAGE_SIZE; \
194 (i <= (((bv)->bv_offset + (bv)->bv_len - 1) / PAGE_SIZE)) && \
195 (pg = bvec_nth_page((bv)->bv_page, i)); i += 1)
196
197#endif /* __LINUX_BVEC_ITER_H */ 192#endif /* __LINUX_BVEC_ITER_H */