1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
23 *
24 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
30
31 /*
32 * University Copyright- Copyright (c) 1982, 1986, 1988
33 * The Regents of the University of California
34 * All Rights Reserved
35 *
36 * University Acknowledgment- Portions of this document are derived from
37 * software developed by the University of California, Berkeley, and its
38 * contributors.
39 */
40
41 #ifndef _SYS_UIO_H
42 #define _SYS_UIO_H
43
44 #include <sys/feature_tests.h>
45
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49
50 #include <sys/types.h>
51
52 /*
53 * I/O parameter information. A uio structure describes the I/O which
54 * is to be performed by an operation. Typically the data movement will
55 * be performed by a routine such as uiomove(), which updates the uio
56 * structure to reflect what was done.
57 */
58
59 #if defined(_XPG4_2)
60 typedef struct iovec {
61 void *iov_base;
62 size_t iov_len;
63 } iovec_t;
64 #else
65 typedef struct iovec {
66 caddr_t iov_base;
67 #if defined(_LP64)
68 size_t iov_len;
69 #else
70 long iov_len;
71 #endif
72 } iovec_t;
73 #endif /* defined(_XPG4_2) */
74
75 #if defined(_SYSCALL32)
76
77 /* Kernel's view of user ILP32 iovec struct */
78
79 typedef struct iovec32 {
80 caddr32_t iov_base;
81 int32_t iov_len;
82 } iovec32_t;
83
84 #endif /* _SYSCALL32 */
85
86 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
87 /*
88 * Segment flag values.
89 */
90 typedef enum uio_seg { UIO_USERSPACE, UIO_SYSSPACE, UIO_USERISPACE } uio_seg_t;
91
92 typedef struct uio {
93 iovec_t *uio_iov; /* pointer to array of iovecs */
94 int uio_iovcnt; /* number of iovecs */
95 lloff_t _uio_offset; /* file offset */
96 uio_seg_t uio_segflg; /* address space (kernel or user) */
97 uint16_t uio_fmode; /* file mode flags */
98 uint16_t uio_extflg; /* extended flags */
99 lloff_t _uio_limit; /* u-limit (maximum byte offset) */
100 ssize_t uio_resid; /* residual count */
101 } uio_t;
102
103 /*
104 * Extended uio_t uioa_t used for asynchronous uio.
105 *
106 * Note: UIOA_IOV_MAX is defined and used as it is in "fs/vncalls.c"
107 * as there isn't a formal definition of IOV_MAX for the kernel.
108 */
109 #define UIOA_IOV_MAX 16
110
111 typedef struct uioa_page_s { /* locked uio_iov state */
112 int uioa_pfncnt; /* count of pfn_t(s) in *uioa_ppp */
113 void **uioa_ppp; /* page_t or pfn_t arrary */
114 caddr_t uioa_base; /* address base */
115 size_t uioa_len; /* span length */
116 } uioa_page_t;
117
118 typedef struct uioa_s {
119 iovec_t *uio_iov; /* pointer to array of iovecs */
120 int uio_iovcnt; /* number of iovecs */
121 lloff_t _uio_offset; /* file offset */
122 uio_seg_t uio_segflg; /* address space (kernel or user) */
123 uint16_t uio_fmode; /* file mode flags */
124 uint16_t uio_extflg; /* extended flags */
125 lloff_t _uio_limit; /* u-limit (maximum byte offset) */
126 ssize_t uio_resid; /* residual count */
127 /*
128 * uioa extended members.
129 */
130 uint32_t uioa_state; /* state of asynch i/o */
131 ssize_t uioa_mbytes; /* bytes that have been uioamove()ed */
132 uioa_page_t *uioa_lcur; /* pointer into uioa_locked[] */
133 void **uioa_lppp; /* pointer into lcur->uioa_ppp[] */
134 void *uioa_hwst[4]; /* opaque hardware state */
135 uioa_page_t uioa_locked[UIOA_IOV_MAX]; /* Per iov locked pages */
136 } uioa_t;
137
138 /*
139 * uio extensions
140 *
141 * PSARC 2009/478: Copy Reduction Interfaces
142 */
143 typedef enum xuio_type {
144 UIOTYPE_ASYNCIO,
145 UIOTYPE_ZEROCOPY
146 } xuio_type_t;
147
148 typedef struct xuio {
149 uio_t xu_uio; /* Embedded UIO structure */
150
151 /* Extended uio fields */
152 enum xuio_type xu_type; /* What kind of uio structure? */
153 union {
154 /* Async I/O Support, intend to replace uioa_t. */
155 struct {
156 uint32_t xu_a_state; /* state of async i/o */
157 /* bytes that have been uioamove()ed */
158 ssize_t xu_a_mbytes;
159 uioa_page_t *xu_a_lcur; /* pointer into uioa_locked[] */
160 /* pointer into lcur->uioa_ppp[] */
161 void **xu_a_lppp;
162 void *xu_a_hwst[4]; /* opaque hardware state */
163 /* Per iov locked pages */
164 uioa_page_t xu_a_locked[UIOA_IOV_MAX];
165 } xu_aio;
166
167 /*
168 * Copy Reduction Support -- facilate loaning / returning of
169 * filesystem cache buffers.
170 */
171 struct {
172 int xu_zc_rw; /* read or write buffer */
173 void *xu_zc_priv; /* fs specific */
174 } xu_zc;
175 } xu_ext;
176 } xuio_t;
177
178 #define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv
179 #define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw
180
181 #define UIOA_ALLOC 0x0001 /* allocated but not yet initialized */
182 #define UIOA_INIT 0x0002 /* initialized but not yet enabled */
183 #define UIOA_ENABLED 0x0004 /* enabled, asynch i/o active */
184 #define UIOA_FINI 0x0008 /* finished waiting for uioafini() */
185
186 #define UIOA_CLR (~0x000F) /* clear mutually exclusive bits */
187
188 #define UIOA_POLL 0x0010 /* need dcopy_poll() */
189
190 #define uio_loffset _uio_offset._f
191 #if !defined(_LP64)
192 #define uio_offset _uio_offset._p._l
193 #else
194 #define uio_offset uio_loffset
195 #endif
196
197 #define uio_llimit _uio_limit._f
198 #if !defined(_LP64)
199 #define uio_limit _uio_limit._p._l
200 #else
201 #define uio_limit uio_llimit
202 #endif
203
204 /*
205 * I/O direction.
206 */
207 typedef enum uio_rw { UIO_READ, UIO_WRITE } uio_rw_t;
208
209 /*
210 * uio_extflg: extended flags
211 *
212 * NOTE: This flag will be used in uiomove to determine if non-temporal
213 * access, ie, access bypassing caches, should be used. Filesystems that
214 * don't initialize this field could experience suboptimal performance due to
215 * the random data the field contains.
216 *
217 * NOTE: This flag is also used by uioasync callers to pass an extended
218 * uio_t (uioa_t), to uioasync enabled consumers. Unlike above all
219 * consumers of a uioa_t require the uio_extflg to be initialized.
220 */
221 #define UIO_COPY_DEFAULT 0x0000 /* no special options to copy */
222 #define UIO_COPY_CACHED 0x0001 /* copy should not bypass caches */
223
224 #define UIO_ASYNC 0x0002 /* uio_t is really a uioa_t */
225 #define UIO_XUIO 0x0004 /* Structure is xuio_t */
226
227 /*
228 * Global uioasync capability shadow state.
229 */
230 typedef struct uioasync_s {
231 boolean_t enabled; /* Is uioasync enabled? */
232 size_t mincnt; /* Minimum byte count for use of */
233 } uioasync_t;
234
235 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
236
237 #if defined(_KERNEL)
238
239 int uiomove(void *, size_t, enum uio_rw, uio_t *);
240 void uio_prefaultpages(ssize_t, uio_t *);
241 int uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *);
242 int ureadc(int, uio_t *); /* should be errno_t in future */
243 int uwritec(struct uio *);
244 void uioskip(uio_t *, size_t);
245 int uiodup(uio_t *, uio_t *, iovec_t *, int);
246
247 int uioamove(void *, size_t, enum uio_rw, uioa_t *);
248 int uioainit(uio_t *, uioa_t *);
249 int uioafini(uio_t *, uioa_t *);
250 extern uioasync_t uioasync;
251
252 #else /* defined(_KERNEL) */
253
254 extern ssize_t readv(int, const struct iovec *, int);
255 extern ssize_t writev(int, const struct iovec *, int);
256
257 #endif /* defined(_KERNEL) */
258
259 #ifdef __cplusplus
260 }
261 #endif
262
263 #endif /* _SYS_UIO_H */