aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-19 01:16:16 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-05-06 17:32:52 -0400
commitf67da30c1d5fc9e341bc8121708874bfd7b31e45 (patch)
tree504966ed27e82dbcbe31786c9a0851a4ae79ef3e /mm
parent5b46f25ddc6edf4adff1a137d453da542c27a640 (diff)
new helper: iov_iter_npages()
counts the pages covered by iov_iter, up to given limit. do_block_direct_io() and fuse_iter_npages() switched to it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'mm')
-rw-r--r--mm/iov_iter.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/mm/iov_iter.c b/mm/iov_iter.c
index 45204cd5ccd8..0b677f8f9bad 100644
--- a/mm/iov_iter.c
+++ b/mm/iov_iter.c
@@ -262,3 +262,30 @@ ssize_t iov_iter_get_pages(struct iov_iter *i,
262 return (res == n ? len : res * PAGE_SIZE) - *start; 262 return (res == n ? len : res * PAGE_SIZE) - *start;
263} 263}
264EXPORT_SYMBOL(iov_iter_get_pages); 264EXPORT_SYMBOL(iov_iter_get_pages);
265
266int iov_iter_npages(const struct iov_iter *i, int maxpages)
267{
268 size_t offset = i->iov_offset;
269 size_t size = i->count;
270 const struct iovec *iov = i->iov;
271 int npages = 0;
272 int n;
273
274 for (n = 0; size && n < i->nr_segs; n++, iov++) {
275 unsigned long addr = (unsigned long)iov->iov_base + offset;
276 size_t len = iov->iov_len - offset;
277 offset = 0;
278 if (unlikely(!len)) /* empty segment */
279 continue;
280 if (len > size)
281 len = size;
282 npages += (addr + len + PAGE_SIZE - 1) / PAGE_SIZE
283 - addr / PAGE_SIZE;
284 if (npages >= maxpages) /* don't bother going further */
285 return maxpages;
286 size -= len;
287 offset = 0;
288 }
289 return min(npages, maxpages);
290}
291EXPORT_SYMBOL(iov_iter_npages);