at v3.15 2.6 kB view raw
1/* 2 * Berkeley style UIO structures - Alan Cox 1994. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 */ 9#ifndef __LINUX_UIO_H 10#define __LINUX_UIO_H 11 12#include <linux/kernel.h> 13#include <uapi/linux/uio.h> 14 15struct page; 16 17struct kvec { 18 void *iov_base; /* and that should *never* hold a userland pointer */ 19 size_t iov_len; 20}; 21 22struct iov_iter { 23 const struct iovec *iov; 24 unsigned long nr_segs; 25 size_t iov_offset; 26 size_t count; 27}; 28 29/* 30 * Total number of bytes covered by an iovec. 31 * 32 * NOTE that it is not safe to use this function until all the iovec's 33 * segment lengths have been validated. Because the individual lengths can 34 * overflow a size_t when added together. 35 */ 36static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs) 37{ 38 unsigned long seg; 39 size_t ret = 0; 40 41 for (seg = 0; seg < nr_segs; seg++) 42 ret += iov[seg].iov_len; 43 return ret; 44} 45 46static inline struct iovec iov_iter_iovec(const struct iov_iter *iter) 47{ 48 return (struct iovec) { 49 .iov_base = iter->iov->iov_base + iter->iov_offset, 50 .iov_len = min(iter->count, 51 iter->iov->iov_len - iter->iov_offset), 52 }; 53} 54 55#define iov_for_each(iov, iter, start) \ 56 for (iter = (start); \ 57 (iter).count && \ 58 ((iov = iov_iter_iovec(&(iter))), 1); \ 59 iov_iter_advance(&(iter), (iov).iov_len)) 60 61unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); 62 63size_t iov_iter_copy_from_user_atomic(struct page *page, 64 struct iov_iter *i, unsigned long offset, size_t bytes); 65size_t iov_iter_copy_from_user(struct page *page, 66 struct iov_iter *i, unsigned long offset, size_t bytes); 67void iov_iter_advance(struct iov_iter *i, size_t bytes); 68int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); 69size_t iov_iter_single_seg_count(const struct iov_iter *i); 70size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, 71 struct iov_iter *i); 72 73static inline void iov_iter_init(struct iov_iter *i, 74 const struct iovec *iov, unsigned long nr_segs, 75 size_t count, size_t written) 76{ 77 i->iov = iov; 78 i->nr_segs = nr_segs; 79 i->iov_offset = 0; 80 i->count = count + written; 81 82 iov_iter_advance(i, written); 83} 84 85static inline size_t iov_iter_count(struct iov_iter *i) 86{ 87 return i->count; 88} 89 90int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); 91int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); 92 93#endif