diff options
-rw-r--r-- | block/bio.c | 18 |
1 files changed, 8 insertions, 10 deletions
diff --git a/block/bio.c b/block/bio.c index f7e3d88bd0b6..cd55ea6bd47c 100644 --- a/block/bio.c +++ b/block/bio.c | |||
@@ -912,16 +912,16 @@ EXPORT_SYMBOL(bio_add_page); | |||
912 | */ | 912 | */ |
913 | int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) | 913 | int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) |
914 | { | 914 | { |
915 | unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt; | 915 | unsigned short nr_pages = bio->bi_max_vecs - bio->bi_vcnt, idx; |
916 | struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; | 916 | struct bio_vec *bv = bio->bi_io_vec + bio->bi_vcnt; |
917 | struct page **pages = (struct page **)bv; | 917 | struct page **pages = (struct page **)bv; |
918 | size_t offset, diff; | 918 | size_t offset; |
919 | ssize_t size; | 919 | ssize_t size; |
920 | 920 | ||
921 | size = iov_iter_get_pages(iter, pages, LONG_MAX, nr_pages, &offset); | 921 | size = iov_iter_get_pages(iter, pages, LONG_MAX, nr_pages, &offset); |
922 | if (unlikely(size <= 0)) | 922 | if (unlikely(size <= 0)) |
923 | return size ? size : -EFAULT; | 923 | return size ? size : -EFAULT; |
924 | nr_pages = (size + offset + PAGE_SIZE - 1) / PAGE_SIZE; | 924 | idx = nr_pages = (size + offset + PAGE_SIZE - 1) / PAGE_SIZE; |
925 | 925 | ||
926 | /* | 926 | /* |
927 | * Deep magic below: We need to walk the pinned pages backwards | 927 | * Deep magic below: We need to walk the pinned pages backwards |
@@ -934,17 +934,15 @@ int bio_iov_iter_get_pages(struct bio *bio, struct iov_iter *iter) | |||
934 | bio->bi_iter.bi_size += size; | 934 | bio->bi_iter.bi_size += size; |
935 | bio->bi_vcnt += nr_pages; | 935 | bio->bi_vcnt += nr_pages; |
936 | 936 | ||
937 | diff = (nr_pages * PAGE_SIZE - offset) - size; | 937 | while (idx--) { |
938 | while (nr_pages--) { | 938 | bv[idx].bv_page = pages[idx]; |
939 | bv[nr_pages].bv_page = pages[nr_pages]; | 939 | bv[idx].bv_len = PAGE_SIZE; |
940 | bv[nr_pages].bv_len = PAGE_SIZE; | 940 | bv[idx].bv_offset = 0; |
941 | bv[nr_pages].bv_offset = 0; | ||
942 | } | 941 | } |
943 | 942 | ||
944 | bv[0].bv_offset += offset; | 943 | bv[0].bv_offset += offset; |
945 | bv[0].bv_len -= offset; | 944 | bv[0].bv_len -= offset; |
946 | if (diff) | 945 | bv[nr_pages - 1].bv_len -= nr_pages * PAGE_SIZE - offset - size; |
947 | bv[bio->bi_vcnt - 1].bv_len -= diff; | ||
948 | 946 | ||
949 | iov_iter_advance(iter, size); | 947 | iov_iter_advance(iter, size); |
950 | return 0; | 948 | return 0; |