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 * Copyright 2013 Nexenta Systems, Inc. All rights reserved. 28 * Copyright (c) 2015, Joyent, Inc. All rights reserved. 29 * Copyright 2026 Oxide Computer Company 30 */ 31 32 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 33 /* All Rights Reserved */ 34 35 /* 36 * University Copyright- Copyright (c) 1982, 1986, 1988 37 * The Regents of the University of California 38 * All Rights Reserved 39 * 40 * University Acknowledgment- Portions of this document are derived from 41 * software developed by the University of California, Berkeley, and its 42 * contributors. 43 */ 44 45 #ifndef _SYS_UIO_H 46 #define _SYS_UIO_H 47 48 #include <sys/feature_tests.h> 49 50 #ifdef __cplusplus 51 extern "C" { 52 #endif 53 54 #include <sys/types.h> 55 56 /* 57 * I/O parameter information. A uio structure describes the I/O which 58 * is to be performed by an operation. Typically the data movement will 59 * be performed by a routine such as uiomove(), which updates the uio 60 * structure to reflect what was done. 61 */ 62 63 #if defined(_XPG4_2) 64 typedef struct iovec { 65 void *iov_base; 66 size_t iov_len; 67 } iovec_t; 68 #else 69 typedef struct iovec { 70 caddr_t iov_base; 71 #if defined(_LP64) 72 size_t iov_len; 73 #else 74 long iov_len; 75 #endif 76 } iovec_t; 77 #endif /* defined(_XPG4_2) */ 78 79 #if defined(_SYSCALL32) 80 81 /* Kernel's view of user ILP32 iovec struct */ 82 83 typedef struct iovec32 { 84 caddr32_t iov_base; 85 int32_t iov_len; 86 } iovec32_t; 87 88 #endif /* _SYSCALL32 */ 89 90 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) 91 /* 92 * Segment flag values. 93 */ 94 typedef enum uio_seg { UIO_USERSPACE, UIO_SYSSPACE, UIO_USERISPACE } uio_seg_t; 95 96 typedef struct uio { 97 iovec_t *uio_iov; /* pointer to array of iovecs */ 98 int uio_iovcnt; /* number of iovecs */ 99 lloff_t _uio_offset; /* file offset */ 100 uio_seg_t uio_segflg; /* address space (kernel or user) */ 101 uint16_t uio_fmode; /* file mode flags */ 102 uint16_t uio_extflg; /* extended flags */ 103 lloff_t _uio_limit; /* u-limit (maximum byte offset) */ 104 ssize_t uio_resid; /* residual count */ 105 } uio_t; 106 107 /* 108 * Extended uio_t uioa_t used for asynchronous uio. 109 * 110 * Note: UIOA_IOV_MAX is defined and used as it is in "fs/vncalls.c" 111 * as there isn't a formal definition of IOV_MAX for the kernel. 112 */ 113 #define UIOA_IOV_MAX 16 114 115 typedef struct uioa_page_s { /* locked uio_iov state */ 116 int uioa_pfncnt; /* count of pfn_t(s) in *uioa_ppp */ 117 void **uioa_ppp; /* page_t or pfn_t arrary */ 118 caddr_t uioa_base; /* address base */ 119 size_t uioa_len; /* span length */ 120 } uioa_page_t; 121 122 typedef struct uioa_s { 123 iovec_t *uio_iov; /* pointer to array of iovecs */ 124 int uio_iovcnt; /* number of iovecs */ 125 lloff_t _uio_offset; /* file offset */ 126 uio_seg_t uio_segflg; /* address space (kernel or user) */ 127 uint16_t uio_fmode; /* file mode flags */ 128 uint16_t uio_extflg; /* extended flags */ 129 lloff_t _uio_limit; /* u-limit (maximum byte offset) */ 130 ssize_t uio_resid; /* residual count */ 131 /* 132 * uioa extended members. 133 */ 134 uint32_t uioa_state; /* state of asynch i/o */ 135 ssize_t uioa_mbytes; /* bytes that have been uioamove()ed */ 136 uioa_page_t *uioa_lcur; /* pointer into uioa_locked[] */ 137 void **uioa_lppp; /* pointer into lcur->uioa_ppp[] */ 138 void *uioa_hwst[4]; /* opaque hardware state */ 139 uioa_page_t uioa_locked[UIOA_IOV_MAX]; /* Per iov locked pages */ 140 } uioa_t; 141 142 /* 143 * uio extensions 144 * 145 * PSARC 2009/478: Copy Reduction Interfaces 146 */ 147 typedef enum xuio_type { 148 UIOTYPE_ASYNCIO, 149 UIOTYPE_ZEROCOPY 150 } xuio_type_t; 151 152 typedef struct xuio { 153 uio_t xu_uio; /* Embedded UIO structure */ 154 155 /* Extended uio fields */ 156 enum xuio_type xu_type; /* What kind of uio structure? */ 157 union { 158 /* Async I/O Support, intend to replace uioa_t. */ 159 struct { 160 uint32_t xu_a_state; /* state of async i/o */ 161 /* bytes that have been uioamove()ed */ 162 ssize_t xu_a_mbytes; 163 uioa_page_t *xu_a_lcur; /* pointer into uioa_locked[] */ 164 /* pointer into lcur->uioa_ppp[] */ 165 void **xu_a_lppp; 166 void *xu_a_hwst[4]; /* opaque hardware state */ 167 /* Per iov locked pages */ 168 uioa_page_t xu_a_locked[UIOA_IOV_MAX]; 169 } xu_aio; 170 171 /* 172 * Copy Reduction Support -- facilate loaning / returning of 173 * filesystem cache buffers. 174 */ 175 struct { 176 int xu_zc_rw; /* read or write buffer */ 177 void *xu_zc_priv; /* fs specific */ 178 } xu_zc; 179 } xu_ext; 180 } xuio_t; 181 182 #define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv 183 #define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw 184 185 #define UIOA_ALLOC 0x0001 /* allocated but not yet initialized */ 186 #define UIOA_INIT 0x0002 /* initialized but not yet enabled */ 187 #define UIOA_ENABLED 0x0004 /* enabled, asynch i/o active */ 188 #define UIOA_FINI 0x0008 /* finished waiting for uioafini() */ 189 190 #define UIOA_CLR (~0x000F) /* clear mutually exclusive bits */ 191 192 #define UIOA_POLL 0x0010 /* need dcopy_poll() */ 193 194 #define uio_loffset _uio_offset._f 195 #if !defined(_LP64) 196 #define uio_offset _uio_offset._p._l 197 #else 198 #define uio_offset uio_loffset 199 #endif 200 201 #define uio_llimit _uio_limit._f 202 #if !defined(_LP64) 203 #define uio_limit _uio_limit._p._l 204 #else 205 #define uio_limit uio_llimit 206 #endif 207 208 /* 209 * I/O direction. 210 */ 211 typedef enum uio_rw { UIO_READ, UIO_WRITE } uio_rw_t; 212 213 /* 214 * uio_extflg: extended flags 215 * 216 * NOTE: This flag will be used in uiomove to determine if non-temporal 217 * access, ie, access bypassing caches, should be used. Filesystems that 218 * don't initialize this field could experience suboptimal performance due to 219 * the random data the field contains. 220 * 221 * NOTE: This flag is also used by uioasync callers to pass an extended 222 * uio_t (uioa_t), to uioasync enabled consumers. Unlike above all 223 * consumers of a uioa_t require the uio_extflg to be initialized. 224 */ 225 #define UIO_COPY_DEFAULT 0x0000 /* no special options to copy */ 226 #define UIO_COPY_CACHED 0x0001 /* copy should not bypass caches */ 227 228 #define UIO_ASYNC 0x0002 /* uio_t is really a uioa_t */ 229 #define UIO_XUIO 0x0004 /* Structure is xuio_t */ 230 231 /* 232 * Global uioasync capability shadow state. 233 */ 234 typedef struct uioasync_s { 235 boolean_t enabled; /* Is uioasync enabled? */ 236 size_t mincnt; /* Minimum byte count for use of */ 237 } uioasync_t; 238 239 #endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */ 240 241 #if defined(_KERNEL) || defined(_FAKE_KERNEL) 242 243 int uiomove(void *, size_t, enum uio_rw, uio_t *); 244 void uio_prefaultpages(ssize_t, uio_t *); 245 int uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *); 246 int ureadc(int, uio_t *); /* should be errno_t in future */ 247 int uwritec(struct uio *); 248 void uioskip(uio_t *, size_t); 249 int uiodup(uio_t *, uio_t *, iovec_t *, int); 250 int uio_copyin(const void *, void *, size_t, uio_seg_t); 251 int uio_copyout(const void *, void *, size_t, uio_seg_t); 252 253 int uioamove(void *, size_t, enum uio_rw, uioa_t *); 254 int uioainit(uio_t *, uioa_t *); 255 int uioafini(uio_t *, uioa_t *); 256 extern uioasync_t uioasync; 257 258 #else /* defined(_KERNEL) */ 259 260 extern ssize_t readv(int, const struct iovec *, int); 261 extern ssize_t writev(int, const struct iovec *, int); 262 263 /* 264 * When in the large file compilation environment, 265 * map preadv/pwritev to their 64 bit offset versions 266 */ 267 #if !defined(_LP64) && _FILE_OFFSET_BITS == 64 268 #ifdef __PRAGMA_REDEFINE_EXTNAME 269 #pragma redefine_extname preadv preadv64 270 #pragma redefine_extname pwritev pwritev64 271 #else /* __PRAGMA_REDEFINE_EXTNAME */ 272 #define preadv preadv64 273 #define pwritev pwritev64 274 #endif /* __PRAGMA_REDEFINE_EXTNAME */ 275 #endif /* !_LP64 && _FILE_OFFSET_BITS == 64 */ 276 277 /* In the LP64 compilation environment, the APIs are already large file */ 278 #if defined(_LP64) && defined(_LARGEFILE64_SOURCE) 279 #ifdef __PRAGMA_REDEFINE_EXTNAME 280 #pragma redefine_extname preadv64 preadv 281 #pragma redefine_extname pwritev64 pwritev 282 #else /* __PRAGMA_REDEFINE_EXTNAME */ 283 #define preadv64 preadv 284 #define pwritev64 pwritev 285 #endif /* __PRAGMA_REDEFINE_EXTNAME */ 286 #endif /* _LP64 && _LARGEFILE64_SOURCE */ 287 288 extern ssize_t preadv(int, const struct iovec *, int, off_t); 289 extern ssize_t pwritev(int, const struct iovec *, int, off_t); 290 291 /* 292 * preadv64 and pwritev64 should be defined when: 293 * - Using the transitional compilation environment, and not 294 * the large file compilation environment. 295 */ 296 #if defined(_LARGEFILE64_SOURCE) && !((_FILE_OFFSET_BITS == 64) && \ 297 !defined(__PRAGMA_REDEFINE_EXTNAME)) 298 extern ssize_t preadv64(int, const struct iovec *, int, off64_t); 299 extern ssize_t pwritev64(int, const struct iovec *, int, off64_t); 300 #endif /* _LARGEFILE64_SOURCE */ 301 302 #endif /* defined(_KERNEL) */ 303 304 #ifdef __cplusplus 305 } 306 #endif 307 308 #endif /* _SYS_UIO_H */ 309