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