diff options
| -rw-r--r-- | lib/iov_iter.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index be4bd627caf0..ea36dc355da1 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
| @@ -861,8 +861,21 @@ EXPORT_SYMBOL(_copy_from_iter_full_nocache); | |||
| 861 | 861 | ||
| 862 | static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) | 862 | static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) |
| 863 | { | 863 | { |
| 864 | struct page *head = compound_head(page); | 864 | struct page *head; |
| 865 | size_t v = n + offset + page_address(page) - page_address(head); | 865 | size_t v = n + offset; |
| 866 | |||
| 867 | /* | ||
| 868 | * The general case needs to access the page order in order | ||
| 869 | * to compute the page size. | ||
| 870 | * However, we mostly deal with order-0 pages and thus can | ||
| 871 | * avoid a possible cache line miss for requests that fit all | ||
| 872 | * page orders. | ||
| 873 | */ | ||
| 874 | if (n <= v && v <= PAGE_SIZE) | ||
| 875 | return true; | ||
| 876 | |||
| 877 | head = compound_head(page); | ||
| 878 | v += (page - head) << PAGE_SHIFT; | ||
| 866 | 879 | ||
| 867 | if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head)))) | 880 | if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head)))) |
| 868 | return true; | 881 | return true; |
