diff options
Diffstat (limited to 'lib/iov_iter.c')
-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; |