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 */