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