diff options
author | Tony Lindgren <tony@atomide.com> | 2017-11-28 08:12:32 -0800 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2017-11-28 08:12:32 -0800 |
commit | bc686442f8a601bccac1f22506ecdb4b0d62cadd (patch) | |
tree | b224ab4aa2350b233da640f5850f48bc6bfeb2d0 /lib/iov_iter.c | |
parent | 60636a5d0fa2f8bc6d0c23c4027100ba20866f9b (diff) | |
parent | ca41e244517d6d3f1600c229ff7ca615049c1e9c (diff) |
Merge branch 'dts-fixes' into omap-for-v4.15/fixes-dt
Diffstat (limited to 'lib/iov_iter.c')
-rw-r--r-- | lib/iov_iter.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 52c8dd6d8e82..970212670b6a 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -687,8 +687,10 @@ EXPORT_SYMBOL(_copy_from_iter_full_nocache); static inline bool page_copy_sane(struct page *page, size_t offset, size_t n) { - size_t v = n + offset; - if (likely(n <= v && v <= (PAGE_SIZE << compound_order(page)))) + struct page *head = compound_head(page); + size_t v = n + offset + page_address(page) - page_address(head); + + if (likely(n <= v && v <= (PAGE_SIZE << compound_order(head)))) return true; WARN_ON(1); return false; @@ -1444,3 +1446,25 @@ int import_single_range(int rw, void __user *buf, size_t len, return 0; } EXPORT_SYMBOL(import_single_range); + +int iov_iter_for_each_range(struct iov_iter *i, size_t bytes, + int (*f)(struct kvec *vec, void *context), + void *context) +{ + struct kvec w; + int err = -EINVAL; + if (!bytes) + return 0; + + iterate_all_kinds(i, bytes, v, -EINVAL, ({ + w.iov_base = kmap(v.bv_page) + v.bv_offset; + w.iov_len = v.bv_len; + err = f(&w, context); + kunmap(v.bv_page); + err;}), ({ + w = v; + err = f(&w, context);}) + ) + return err; +} +EXPORT_SYMBOL(iov_iter_for_each_range); |