iov_iter.c revision 91f79c43d1b54d7154b118860d81b39bad07dfff
14f18cd317a118c28482f97303600a2fe2ada6c79Al Viro#include <linux/export.h>
24f18cd317a118c28482f97303600a2fe2ada6c79Al Viro#include <linux/uio.h>
34f18cd317a118c28482f97303600a2fe2ada6c79Al Viro#include <linux/pagemap.h>
491f79c43d1b54d7154b118860d81b39bad07dfffAl Viro#include <linux/slab.h>
591f79c43d1b54d7154b118860d81b39bad07dfffAl Viro#include <linux/vmalloc.h>
64f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
74f18cd317a118c28482f97303600a2fe2ada6c79Al Virosize_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
84f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			 struct iov_iter *i)
94f18cd317a118c28482f97303600a2fe2ada6c79Al Viro{
104f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	size_t skip, copy, left, wanted;
114f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	const struct iovec *iov;
124f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	char __user *buf;
134f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	void *kaddr, *from;
144f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
154f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	if (unlikely(bytes > i->count))
164f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		bytes = i->count;
174f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
184f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	if (unlikely(!bytes))
194f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		return 0;
204f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
214f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	wanted = bytes;
224f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	iov = i->iov;
234f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	skip = i->iov_offset;
244f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	buf = iov->iov_base + skip;
254f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	copy = min(bytes, iov->iov_len - skip);
264f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
274f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	if (!fault_in_pages_writeable(buf, copy)) {
284f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		kaddr = kmap_atomic(page);
294f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		from = kaddr + offset;
304f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
314f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		/* first chunk, usually the only one */
324f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		left = __copy_to_user_inatomic(buf, from, copy);
334f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copy -= left;
344f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		skip += copy;
354f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		from += copy;
364f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		bytes -= copy;
374f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
384f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		while (unlikely(!left && bytes)) {
394f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			iov++;
404f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			buf = iov->iov_base;
414f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			copy = min(bytes, iov->iov_len);
424f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			left = __copy_to_user_inatomic(buf, from, copy);
434f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			copy -= left;
444f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			skip = copy;
454f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			from += copy;
464f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			bytes -= copy;
474f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		}
484f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		if (likely(!bytes)) {
494f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			kunmap_atomic(kaddr);
504f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			goto done;
514f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		}
524f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		offset = from - kaddr;
534f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		buf += copy;
544f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		kunmap_atomic(kaddr);
554f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copy = min(bytes, iov->iov_len - skip);
564f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	}
574f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	/* Too bad - revert to non-atomic kmap */
584f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	kaddr = kmap(page);
594f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	from = kaddr + offset;
604f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	left = __copy_to_user(buf, from, copy);
614f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	copy -= left;
624f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	skip += copy;
634f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	from += copy;
644f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	bytes -= copy;
654f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	while (unlikely(!left && bytes)) {
664f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		iov++;
674f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		buf = iov->iov_base;
684f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copy = min(bytes, iov->iov_len);
694f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		left = __copy_to_user(buf, from, copy);
704f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copy -= left;
714f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		skip = copy;
724f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		from += copy;
734f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		bytes -= copy;
744f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	}
754f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	kunmap(page);
764f18cd317a118c28482f97303600a2fe2ada6c79Al Virodone:
774f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	i->count -= wanted - bytes;
784f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	i->nr_segs -= iov - i->iov;
794f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	i->iov = iov;
804f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	i->iov_offset = skip;
814f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	return wanted - bytes;
824f18cd317a118c28482f97303600a2fe2ada6c79Al Viro}
834f18cd317a118c28482f97303600a2fe2ada6c79Al ViroEXPORT_SYMBOL(copy_page_to_iter);
844f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
854f18cd317a118c28482f97303600a2fe2ada6c79Al Virostatic size_t __iovec_copy_from_user_inatomic(char *vaddr,
864f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			const struct iovec *iov, size_t base, size_t bytes)
874f18cd317a118c28482f97303600a2fe2ada6c79Al Viro{
884f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	size_t copied = 0, left = 0;
894f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
904f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	while (bytes) {
914f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		char __user *buf = iov->iov_base + base;
924f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		int copy = min(bytes, iov->iov_len - base);
934f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
944f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		base = 0;
954f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		left = __copy_from_user_inatomic(vaddr, buf, copy);
964f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copied += copy;
974f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		bytes -= copy;
984f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		vaddr += copy;
994f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		iov++;
1004f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1014f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		if (unlikely(left))
1024f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			break;
1034f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	}
1044f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	return copied - left;
1054f18cd317a118c28482f97303600a2fe2ada6c79Al Viro}
1064f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1074f18cd317a118c28482f97303600a2fe2ada6c79Al Viro/*
1084f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * Copy as much as we can into the page and return the number of bytes which
1094f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * were successfully copied.  If a fault is encountered then return the number of
1104f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * bytes which were copied.
1114f18cd317a118c28482f97303600a2fe2ada6c79Al Viro */
1124f18cd317a118c28482f97303600a2fe2ada6c79Al Virosize_t iov_iter_copy_from_user_atomic(struct page *page,
1134f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		struct iov_iter *i, unsigned long offset, size_t bytes)
1144f18cd317a118c28482f97303600a2fe2ada6c79Al Viro{
1154f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	char *kaddr;
1164f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	size_t copied;
1174f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1184f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	kaddr = kmap_atomic(page);
1194f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	if (likely(i->nr_segs == 1)) {
1204f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		int left;
1214f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		char __user *buf = i->iov->iov_base + i->iov_offset;
1224f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		left = __copy_from_user_inatomic(kaddr + offset, buf, bytes);
1234f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copied = bytes - left;
1244f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	} else {
1254f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		copied = __iovec_copy_from_user_inatomic(kaddr + offset,
1264f18cd317a118c28482f97303600a2fe2ada6c79Al Viro						i->iov, i->iov_offset, bytes);
1274f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	}
1284f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	kunmap_atomic(kaddr);
1294f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1304f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	return copied;
1314f18cd317a118c28482f97303600a2fe2ada6c79Al Viro}
1324f18cd317a118c28482f97303600a2fe2ada6c79Al ViroEXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
1334f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1344f18cd317a118c28482f97303600a2fe2ada6c79Al Virovoid iov_iter_advance(struct iov_iter *i, size_t bytes)
1354f18cd317a118c28482f97303600a2fe2ada6c79Al Viro{
1364f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	BUG_ON(i->count < bytes);
1374f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1384f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	if (likely(i->nr_segs == 1)) {
1394f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		i->iov_offset += bytes;
1404f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		i->count -= bytes;
1414f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	} else {
1424f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		const struct iovec *iov = i->iov;
1434f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		size_t base = i->iov_offset;
1444f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		unsigned long nr_segs = i->nr_segs;
1454f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1464f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		/*
1474f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		 * The !iov->iov_len check ensures we skip over unlikely
1484f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		 * zero-length segments (without overruning the iovec).
1494f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		 */
1504f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		while (bytes || unlikely(i->count && !iov->iov_len)) {
1514f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			int copy;
1524f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1534f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			copy = min(bytes, iov->iov_len - base);
1544f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			BUG_ON(!i->count || i->count < copy);
1554f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			i->count -= copy;
1564f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			bytes -= copy;
1574f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			base += copy;
1584f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			if (iov->iov_len == base) {
1594f18cd317a118c28482f97303600a2fe2ada6c79Al Viro				iov++;
1604f18cd317a118c28482f97303600a2fe2ada6c79Al Viro				nr_segs--;
1614f18cd317a118c28482f97303600a2fe2ada6c79Al Viro				base = 0;
1624f18cd317a118c28482f97303600a2fe2ada6c79Al Viro			}
1634f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		}
1644f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		i->iov = iov;
1654f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		i->iov_offset = base;
1664f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		i->nr_segs = nr_segs;
1674f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	}
1684f18cd317a118c28482f97303600a2fe2ada6c79Al Viro}
1694f18cd317a118c28482f97303600a2fe2ada6c79Al ViroEXPORT_SYMBOL(iov_iter_advance);
1704f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1714f18cd317a118c28482f97303600a2fe2ada6c79Al Viro/*
1724f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * Fault in the first iovec of the given iov_iter, to a maximum length
1734f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * of bytes. Returns 0 on success, or non-zero if the memory could not be
1744f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * accessed (ie. because it is an invalid address).
1754f18cd317a118c28482f97303600a2fe2ada6c79Al Viro *
1764f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * writev-intensive code may want this to prefault several iovecs -- that
1774f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * would be possible (callers must not rely on the fact that _only_ the
1784f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * first iovec will be faulted with the current implementation).
1794f18cd317a118c28482f97303600a2fe2ada6c79Al Viro */
1804f18cd317a118c28482f97303600a2fe2ada6c79Al Viroint iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
1814f18cd317a118c28482f97303600a2fe2ada6c79Al Viro{
1824f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	char __user *buf = i->iov->iov_base + i->iov_offset;
1834f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	bytes = min(bytes, i->iov->iov_len - i->iov_offset);
1844f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	return fault_in_pages_readable(buf, bytes);
1854f18cd317a118c28482f97303600a2fe2ada6c79Al Viro}
1864f18cd317a118c28482f97303600a2fe2ada6c79Al ViroEXPORT_SYMBOL(iov_iter_fault_in_readable);
1874f18cd317a118c28482f97303600a2fe2ada6c79Al Viro
1884f18cd317a118c28482f97303600a2fe2ada6c79Al Viro/*
1894f18cd317a118c28482f97303600a2fe2ada6c79Al Viro * Return the count of just the current iov_iter segment.
1904f18cd317a118c28482f97303600a2fe2ada6c79Al Viro */
1914f18cd317a118c28482f97303600a2fe2ada6c79Al Virosize_t iov_iter_single_seg_count(const struct iov_iter *i)
1924f18cd317a118c28482f97303600a2fe2ada6c79Al Viro{
1934f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	const struct iovec *iov = i->iov;
1944f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	if (i->nr_segs == 1)
1954f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		return i->count;
1964f18cd317a118c28482f97303600a2fe2ada6c79Al Viro	else
1974f18cd317a118c28482f97303600a2fe2ada6c79Al Viro		return min(i->count, iov->iov_len - i->iov_offset);
1984f18cd317a118c28482f97303600a2fe2ada6c79Al Viro}
1994f18cd317a118c28482f97303600a2fe2ada6c79Al ViroEXPORT_SYMBOL(iov_iter_single_seg_count);
200886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro
201886a39115005ced8b15ab067c9c2a8d546b40a5eAl Virounsigned long iov_iter_alignment(const struct iov_iter *i)
202886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro{
203886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	const struct iovec *iov = i->iov;
204886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	unsigned long res;
205886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	size_t size = i->count;
206886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	size_t n;
207886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro
208886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	if (!size)
209886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro		return 0;
210886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro
211886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	res = (unsigned long)iov->iov_base + i->iov_offset;
212886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	n = iov->iov_len - i->iov_offset;
213886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	if (n >= size)
214886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro		return res | size;
215886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	size -= n;
216886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	res |= n;
217886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	while (size > (++iov)->iov_len) {
218886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro		res |= (unsigned long)iov->iov_base | iov->iov_len;
219886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro		size -= iov->iov_len;
220886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	}
221886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	res |= (unsigned long)iov->iov_base | size;
222886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro	return res;
223886a39115005ced8b15ab067c9c2a8d546b40a5eAl Viro}
224886a39115005ced8b15ab067c9c2a8d546b40a5eAl ViroEXPORT_SYMBOL(iov_iter_alignment);
22571d8e532b1549a478e6a6a8a44f309d050294d00Al Viro
22671d8e532b1549a478e6a6a8a44f309d050294d00Al Virovoid iov_iter_init(struct iov_iter *i, int direction,
22771d8e532b1549a478e6a6a8a44f309d050294d00Al Viro			const struct iovec *iov, unsigned long nr_segs,
22871d8e532b1549a478e6a6a8a44f309d050294d00Al Viro			size_t count)
22971d8e532b1549a478e6a6a8a44f309d050294d00Al Viro{
23071d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	/* It will get better.  Eventually... */
23171d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	if (segment_eq(get_fs(), KERNEL_DS))
23271d8e532b1549a478e6a6a8a44f309d050294d00Al Viro		direction |= REQ_KERNEL;
23371d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	i->type = direction;
23471d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	i->iov = iov;
23571d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	i->nr_segs = nr_segs;
23671d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	i->iov_offset = 0;
23771d8e532b1549a478e6a6a8a44f309d050294d00Al Viro	i->count = count;
23871d8e532b1549a478e6a6a8a44f309d050294d00Al Viro}
23971d8e532b1549a478e6a6a8a44f309d050294d00Al ViroEXPORT_SYMBOL(iov_iter_init);
2407b2c99d15559e285384c742db52316802e24b0bdAl Viro
2417b2c99d15559e285384c742db52316802e24b0bdAl Virossize_t iov_iter_get_pages(struct iov_iter *i,
2427b2c99d15559e285384c742db52316802e24b0bdAl Viro		   struct page **pages, size_t maxsize,
2437b2c99d15559e285384c742db52316802e24b0bdAl Viro		   size_t *start)
2447b2c99d15559e285384c742db52316802e24b0bdAl Viro{
2457b2c99d15559e285384c742db52316802e24b0bdAl Viro	size_t offset = i->iov_offset;
2467b2c99d15559e285384c742db52316802e24b0bdAl Viro	const struct iovec *iov = i->iov;
2477b2c99d15559e285384c742db52316802e24b0bdAl Viro	size_t len;
2487b2c99d15559e285384c742db52316802e24b0bdAl Viro	unsigned long addr;
2497b2c99d15559e285384c742db52316802e24b0bdAl Viro	int n;
2507b2c99d15559e285384c742db52316802e24b0bdAl Viro	int res;
2517b2c99d15559e285384c742db52316802e24b0bdAl Viro
2527b2c99d15559e285384c742db52316802e24b0bdAl Viro	len = iov->iov_len - offset;
2537b2c99d15559e285384c742db52316802e24b0bdAl Viro	if (len > i->count)
2547b2c99d15559e285384c742db52316802e24b0bdAl Viro		len = i->count;
2557b2c99d15559e285384c742db52316802e24b0bdAl Viro	if (len > maxsize)
2567b2c99d15559e285384c742db52316802e24b0bdAl Viro		len = maxsize;
2577b2c99d15559e285384c742db52316802e24b0bdAl Viro	addr = (unsigned long)iov->iov_base + offset;
2587b2c99d15559e285384c742db52316802e24b0bdAl Viro	len += *start = addr & (PAGE_SIZE - 1);
2597b2c99d15559e285384c742db52316802e24b0bdAl Viro	addr &= ~(PAGE_SIZE - 1);
2607b2c99d15559e285384c742db52316802e24b0bdAl Viro	n = (len + PAGE_SIZE - 1) / PAGE_SIZE;
2617b2c99d15559e285384c742db52316802e24b0bdAl Viro	res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, pages);
2627b2c99d15559e285384c742db52316802e24b0bdAl Viro	if (unlikely(res < 0))
2637b2c99d15559e285384c742db52316802e24b0bdAl Viro		return res;
2647b2c99d15559e285384c742db52316802e24b0bdAl Viro	return (res == n ? len : res * PAGE_SIZE) - *start;
2657b2c99d15559e285384c742db52316802e24b0bdAl Viro}
2667b2c99d15559e285384c742db52316802e24b0bdAl ViroEXPORT_SYMBOL(iov_iter_get_pages);
267f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro
26891f79c43d1b54d7154b118860d81b39bad07dfffAl Virossize_t iov_iter_get_pages_alloc(struct iov_iter *i,
26991f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		   struct page ***pages, size_t maxsize,
27091f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		   size_t *start)
27191f79c43d1b54d7154b118860d81b39bad07dfffAl Viro{
27291f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	size_t offset = i->iov_offset;
27391f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	const struct iovec *iov = i->iov;
27491f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	size_t len;
27591f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	unsigned long addr;
27691f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	void *p;
27791f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	int n;
27891f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	int res;
27991f79c43d1b54d7154b118860d81b39bad07dfffAl Viro
28091f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	len = iov->iov_len - offset;
28191f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	if (len > i->count)
28291f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		len = i->count;
28391f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	if (len > maxsize)
28491f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		len = maxsize;
28591f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	addr = (unsigned long)iov->iov_base + offset;
28691f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	len += *start = addr & (PAGE_SIZE - 1);
28791f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	addr &= ~(PAGE_SIZE - 1);
28891f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	n = (len + PAGE_SIZE - 1) / PAGE_SIZE;
28991f79c43d1b54d7154b118860d81b39bad07dfffAl Viro
29091f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	p = kmalloc(n * sizeof(struct page *), GFP_KERNEL);
29191f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	if (!p)
29291f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		p = vmalloc(n * sizeof(struct page *));
29391f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	if (!p)
29491f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		return -ENOMEM;
29591f79c43d1b54d7154b118860d81b39bad07dfffAl Viro
29691f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	res = get_user_pages_fast(addr, n, (i->type & WRITE) != WRITE, p);
29791f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	if (unlikely(res < 0)) {
29891f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		kvfree(p);
29991f79c43d1b54d7154b118860d81b39bad07dfffAl Viro		return res;
30091f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	}
30191f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	*pages = p;
30291f79c43d1b54d7154b118860d81b39bad07dfffAl Viro	return (res == n ? len : res * PAGE_SIZE) - *start;
30391f79c43d1b54d7154b118860d81b39bad07dfffAl Viro}
30491f79c43d1b54d7154b118860d81b39bad07dfffAl ViroEXPORT_SYMBOL(iov_iter_get_pages_alloc);
30591f79c43d1b54d7154b118860d81b39bad07dfffAl Viro
306f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viroint iov_iter_npages(const struct iov_iter *i, int maxpages)
307f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro{
308f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	size_t offset = i->iov_offset;
309f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	size_t size = i->count;
310f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	const struct iovec *iov = i->iov;
311f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	int npages = 0;
312f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	int n;
313f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro
314f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	for (n = 0; size && n < i->nr_segs; n++, iov++) {
315f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		unsigned long addr = (unsigned long)iov->iov_base + offset;
316f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		size_t len = iov->iov_len - offset;
317f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		offset = 0;
318f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		if (unlikely(!len))	/* empty segment */
319f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro			continue;
320f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		if (len > size)
321f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro			len = size;
322f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		npages += (addr + len + PAGE_SIZE - 1) / PAGE_SIZE
323f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro			  - addr / PAGE_SIZE;
324f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		if (npages >= maxpages)	/* don't bother going further */
325f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro			return maxpages;
326f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		size -= len;
327f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro		offset = 0;
328f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	}
329f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro	return min(npages, maxpages);
330f67da30c1d5fc9e341bc8121708874bfd7b31e45Al Viro}
331f67da30c1d5fc9e341bc8121708874bfd7b31e45Al ViroEXPORT_SYMBOL(iov_iter_npages);
332