diff options
Diffstat (limited to 'include/linux/uio.h')
-rw-r--r-- | include/linux/uio.h | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/include/linux/uio.h b/include/linux/uio.h index c55ce243cc09..199bcc34241b 100644 --- a/include/linux/uio.h +++ b/include/linux/uio.h | |||
@@ -9,14 +9,23 @@ | |||
9 | #ifndef __LINUX_UIO_H | 9 | #ifndef __LINUX_UIO_H |
10 | #define __LINUX_UIO_H | 10 | #define __LINUX_UIO_H |
11 | 11 | ||
12 | #include <linux/kernel.h> | ||
12 | #include <uapi/linux/uio.h> | 13 | #include <uapi/linux/uio.h> |
13 | 14 | ||
15 | struct page; | ||
14 | 16 | ||
15 | struct kvec { | 17 | struct kvec { |
16 | void *iov_base; /* and that should *never* hold a userland pointer */ | 18 | void *iov_base; /* and that should *never* hold a userland pointer */ |
17 | size_t iov_len; | 19 | size_t iov_len; |
18 | }; | 20 | }; |
19 | 21 | ||
22 | struct iov_iter { | ||
23 | const struct iovec *iov; | ||
24 | unsigned long nr_segs; | ||
25 | size_t iov_offset; | ||
26 | size_t count; | ||
27 | }; | ||
28 | |||
20 | /* | 29 | /* |
21 | * Total number of bytes covered by an iovec. | 30 | * Total number of bytes covered by an iovec. |
22 | * | 31 | * |
@@ -34,8 +43,51 @@ static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs) | |||
34 | return ret; | 43 | return ret; |
35 | } | 44 | } |
36 | 45 | ||
46 | static 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 | |||
37 | unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); | 61 | unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to); |
38 | 62 | ||
63 | size_t iov_iter_copy_from_user_atomic(struct page *page, | ||
64 | struct iov_iter *i, unsigned long offset, size_t bytes); | ||
65 | size_t iov_iter_copy_from_user(struct page *page, | ||
66 | struct iov_iter *i, unsigned long offset, size_t bytes); | ||
67 | void iov_iter_advance(struct iov_iter *i, size_t bytes); | ||
68 | int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes); | ||
69 | size_t iov_iter_single_seg_count(const struct iov_iter *i); | ||
70 | size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes, | ||
71 | struct iov_iter *i); | ||
72 | |||
73 | static 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 | |||
85 | static inline size_t iov_iter_count(struct iov_iter *i) | ||
86 | { | ||
87 | return i->count; | ||
88 | } | ||
89 | |||
39 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); | 90 | int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len); |
40 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); | 91 | int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len); |
92 | |||
41 | #endif | 93 | #endif |