diff options
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r-- | lib/iov_iter.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index be4bd627caf0..b396d328a764 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -861,8 +861,21 @@ EXPORT_SYMBOL(_copy_from_iter_full_nocache); static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) { - struct page *head = compound_head(page); - size_t v = n + offset + page_address(page) - page_address(head); + struct page *head; + size_t v = n + offset; + + /* + * The general case needs to access the page order in order + * to compute the page size. + * However, we mostly deal with order-0 pages and thus can + * avoid a possible cache line miss for requests that fit all + * page orders. + */ + if (n <= v && v <= PAGE_SIZE) + return true; + + head = compound_head(page); + v += (page - head) << PAGE_SHIFT; if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head)))) return true; @@ -1515,6 +1528,7 @@ EXPORT_SYMBOL(csum_and_copy_to_iter); size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, struct iov_iter *i) { +#ifdef CONFIG_CRYPTO struct ahash_request *hash = hashp; struct scatterlist sg; size_t copied; @@ -1524,6 +1538,9 @@ size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp, ahash_request_set_crypt(hash, &sg, NULL, copied); crypto_ahash_update(hash); return copied; +#else + return 0; +#endif } EXPORT_SYMBOL(hash_and_copy_to_iter); |