source: src/linux/universal/linux-4.9/include/linux/uio.h @ 31885

Last change on this file since 31885 was 31885, checked in by brainslayer, 3 months ago

update

File size: 5.5 KB
Line 
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;
16struct pipe_inode_info;
17
18struct kvec {
19        void *iov_base; /* and that should *never* hold a userland pointer */
20        size_t iov_len;
21};
22
23enum {
24        ITER_IOVEC = 0,
25        ITER_KVEC = 2,
26        ITER_BVEC = 4,
27        ITER_PIPE = 8,
28};
29
30struct iov_iter {
31        int type;
32        size_t iov_offset;
33        size_t count;
34        union {
35                const struct iovec *iov;
36                const struct kvec *kvec;
37                const struct bio_vec *bvec;
38                struct pipe_inode_info *pipe;
39        };
40        union {
41                unsigned long nr_segs;
42                struct {
43                        int idx;
44                        int start_idx;
45                };
46        };
47};
48
49/*
50 * Total number of bytes covered by an iovec.
51 *
52 * NOTE that it is not safe to use this function until all the iovec's
53 * segment lengths have been validated.  Because the individual lengths can
54 * overflow a size_t when added together.
55 */
56static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
57{
58        unsigned long seg;
59        size_t ret = 0;
60
61        for (seg = 0; seg < nr_segs; seg++)
62                ret += iov[seg].iov_len;
63        return ret;
64}
65
66static inline struct iovec iov_iter_iovec(const struct iov_iter *iter)
67{
68        return (struct iovec) {
69                .iov_base = iter->iov->iov_base + iter->iov_offset,
70                .iov_len = min(iter->count,
71                               iter->iov->iov_len - iter->iov_offset),
72        };
73}
74
75#define iov_for_each(iov, iter, start)                          \
76        if (!((start).type & (ITER_BVEC | ITER_PIPE)))          \
77        for (iter = (start);                                    \
78             (iter).count &&                                    \
79             ((iov = iov_iter_iovec(&(iter))), 1);              \
80             iov_iter_advance(&(iter), (iov).iov_len))
81
82unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to);
83
84size_t iov_iter_copy_from_user_atomic(struct page *page,
85                struct iov_iter *i, unsigned long offset, size_t bytes);
86void iov_iter_advance(struct iov_iter *i, size_t bytes);
87void iov_iter_revert(struct iov_iter *i, size_t bytes);
88int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
89size_t iov_iter_single_seg_count(const struct iov_iter *i);
90size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
91                         struct iov_iter *i);
92size_t copy_page_from_iter(struct page *page, size_t offset, size_t bytes,
93                         struct iov_iter *i);
94size_t copy_to_iter(const void *addr, size_t bytes, struct iov_iter *i);
95size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i);
96size_t copy_from_iter_nocache(void *addr, size_t bytes, struct iov_iter *i);
97size_t iov_iter_zero(size_t bytes, struct iov_iter *);
98unsigned long iov_iter_alignment(const struct iov_iter *i);
99unsigned long iov_iter_gap_alignment(const struct iov_iter *i);
100void iov_iter_init(struct iov_iter *i, int direction, const struct iovec *iov,
101                        unsigned long nr_segs, size_t count);
102void iov_iter_kvec(struct iov_iter *i, int direction, const struct kvec *kvec,
103                        unsigned long nr_segs, size_t count);
104void iov_iter_bvec(struct iov_iter *i, int direction, const struct bio_vec *bvec,
105                        unsigned long nr_segs, size_t count);
106void iov_iter_pipe(struct iov_iter *i, int direction, struct pipe_inode_info *pipe,
107                        size_t count);
108ssize_t iov_iter_get_pages(struct iov_iter *i, struct page **pages,
109                        size_t maxsize, unsigned maxpages, size_t *start);
110ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, struct page ***pages,
111                        size_t maxsize, size_t *start);
112int iov_iter_npages(const struct iov_iter *i, int maxpages);
113
114const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags);
115
116static inline size_t iov_iter_count(const struct iov_iter *i)
117{
118        return i->count;
119}
120
121static inline bool iter_is_iovec(const struct iov_iter *i)
122{
123        return !(i->type & (ITER_BVEC | ITER_KVEC | ITER_PIPE));
124}
125
126/*
127 * Get one of READ or WRITE out of iter->type without any other flags OR'd in
128 * with it.
129 *
130 * The ?: is just for type safety.
131 */
132#define iov_iter_rw(i) ((0 ? (struct iov_iter *)0 : (i))->type & RW_MASK)
133
134/*
135 * Cap the iov_iter by given limit; note that the second argument is
136 * *not* the new size - it's upper limit for such.  Passing it a value
137 * greater than the amount of data in iov_iter is fine - it'll just do
138 * nothing in that case.
139 */
140static inline void iov_iter_truncate(struct iov_iter *i, u64 count)
141{
142        /*
143         * count doesn't have to fit in size_t - comparison extends both
144         * operands to u64 here and any value that would be truncated by
145         * conversion in assignement is by definition greater than all
146         * values of size_t, including old i->count.
147         */
148        if (i->count > count)
149                i->count = count;
150}
151
152/*
153 * reexpand a previously truncated iterator; count must be no more than how much
154 * we had shrunk it.
155 */
156static inline void iov_iter_reexpand(struct iov_iter *i, size_t count)
157{
158        i->count = count;
159}
160size_t csum_and_copy_to_iter(const void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
161size_t csum_and_copy_from_iter(void *addr, size_t bytes, __wsum *csum, struct iov_iter *i);
162
163int import_iovec(int type, const struct iovec __user * uvector,
164                 unsigned nr_segs, unsigned fast_segs,
165                 struct iovec **iov, struct iov_iter *i);
166
167#ifdef CONFIG_COMPAT
168struct compat_iovec;
169int compat_import_iovec(int type, const struct compat_iovec __user * uvector,
170                 unsigned nr_segs, unsigned fast_segs,
171                 struct iovec **iov, struct iov_iter *i);
172#endif
173
174int import_single_range(int type, void __user *buf, size_t len,
175                 struct iovec *iov, struct iov_iter *i);
176
177#endif
Note: See TracBrowser for help on using the repository browser.