diff options
-rw-r--r-- | fs/bio.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -815,28 +815,30 @@ struct bio *bio_copy_user_iov(struct request_queue *q, | |||
815 | 815 | ||
816 | ret = 0; | 816 | ret = 0; |
817 | i = 0; | 817 | i = 0; |
818 | if (map_data) | ||
819 | nr_pages = 1 << map_data->page_order; | ||
818 | while (len) { | 820 | while (len) { |
819 | unsigned int bytes; | 821 | unsigned int bytes = PAGE_SIZE; |
820 | |||
821 | if (map_data) | ||
822 | bytes = 1U << (PAGE_SHIFT + map_data->page_order); | ||
823 | else | ||
824 | bytes = PAGE_SIZE; | ||
825 | 822 | ||
826 | if (bytes > len) | 823 | if (bytes > len) |
827 | bytes = len; | 824 | bytes = len; |
828 | 825 | ||
829 | if (map_data) { | 826 | if (map_data) { |
830 | if (i == map_data->nr_entries) { | 827 | if (i == map_data->nr_entries * nr_pages) { |
831 | ret = -ENOMEM; | 828 | ret = -ENOMEM; |
832 | break; | 829 | break; |
833 | } | 830 | } |
834 | page = map_data->pages[i++]; | 831 | |
835 | } else | 832 | page = map_data->pages[i / nr_pages]; |
833 | page += (i % nr_pages); | ||
834 | |||
835 | i++; | ||
836 | } else { | ||
836 | page = alloc_page(q->bounce_gfp | gfp_mask); | 837 | page = alloc_page(q->bounce_gfp | gfp_mask); |
837 | if (!page) { | 838 | if (!page) { |
838 | ret = -ENOMEM; | 839 | ret = -ENOMEM; |
839 | break; | 840 | break; |
841 | } | ||
840 | } | 842 | } |
841 | 843 | ||
842 | if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) | 844 | if (bio_add_pc_page(q, bio, page, bytes, 0) < bytes) |