summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/uio.h
blob: 9584be559f07c798922ea768e5598db9ad0cfcd2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
 *
 * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
 * Copyright (c) 2015, Joyent, Inc.  All rights reserved.
 */

/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
/*	  All Rights Reserved	*/

/*
 * University Copyright- Copyright (c) 1982, 1986, 1988
 * The Regents of the University of California
 * All Rights Reserved
 *
 * University Acknowledgment- Portions of this document are derived from
 * software developed by the University of California, Berkeley, and its
 * contributors.
 */

#ifndef _SYS_UIO_H
#define	_SYS_UIO_H

#include <sys/feature_tests.h>

#ifdef	__cplusplus
extern "C" {
#endif

#include <sys/types.h>

/*
 * I/O parameter information.  A uio structure describes the I/O which
 * is to be performed by an operation.  Typically the data movement will
 * be performed by a routine such as uiomove(), which updates the uio
 * structure to reflect what was done.
 */

#if	defined(_XPG4_2)
typedef struct iovec {
	void	*iov_base;
	size_t	iov_len;
} iovec_t;
#else
typedef struct iovec {
	caddr_t	iov_base;
#if defined(_LP64)
	size_t	iov_len;
#else
	long	iov_len;
#endif
} iovec_t;
#endif	/* defined(_XPG4_2) */

#if defined(_SYSCALL32)

/* Kernel's view of user ILP32 iovec struct */

typedef	struct iovec32 {
	caddr32_t	iov_base;
	int32_t		iov_len;
} iovec32_t;

#endif	/* _SYSCALL32 */

#if 	!defined(_XPG4_2) || defined(__EXTENSIONS__)
/*
 * Segment flag values.
 */
typedef enum uio_seg { UIO_USERSPACE, UIO_SYSSPACE, UIO_USERISPACE } uio_seg_t;

typedef struct uio {
	iovec_t		*uio_iov;	/* pointer to array of iovecs */
	int		uio_iovcnt;	/* number of iovecs */
	lloff_t		_uio_offset;	/* file offset */
	uio_seg_t	uio_segflg;	/* address space (kernel or user) */
	uint16_t	uio_fmode;	/* file mode flags */
	uint16_t	uio_extflg;	/* extended flags */
	lloff_t		_uio_limit;	/* u-limit (maximum byte offset) */
	ssize_t		uio_resid;	/* residual count */
} uio_t;

/*
 * Extended uio_t uioa_t used for asynchronous uio.
 *
 * Note: UIOA_IOV_MAX is defined and used as it is in "fs/vncalls.c"
 *	 as there isn't a formal definition of IOV_MAX for the kernel.
 */
#define	UIOA_IOV_MAX	16

typedef struct uioa_page_s {		/* locked uio_iov state */
	int	uioa_pfncnt;		/* count of pfn_t(s) in *uioa_ppp */
	void	**uioa_ppp;		/* page_t or pfn_t arrary */
	caddr_t	uioa_base;		/* address base */
	size_t	uioa_len;		/* span length */
} uioa_page_t;

typedef struct uioa_s {
	iovec_t		*uio_iov;	/* pointer to array of iovecs */
	int		uio_iovcnt;	/* number of iovecs */
	lloff_t		_uio_offset;	/* file offset */
	uio_seg_t	uio_segflg;	/* address space (kernel or user) */
	uint16_t	uio_fmode;	/* file mode flags */
	uint16_t	uio_extflg;	/* extended flags */
	lloff_t		_uio_limit;	/* u-limit (maximum byte offset) */
	ssize_t		uio_resid;	/* residual count */
	/*
	 * uioa extended members.
	 */
	uint32_t	uioa_state;	/* state of asynch i/o */
	ssize_t		uioa_mbytes;	/* bytes that have been uioamove()ed */
	uioa_page_t	*uioa_lcur;	/* pointer into uioa_locked[] */
	void		**uioa_lppp;	/* pointer into lcur->uioa_ppp[] */
	void		*uioa_hwst[4];	/* opaque hardware state */
	uioa_page_t	uioa_locked[UIOA_IOV_MAX]; /* Per iov locked pages */
} uioa_t;

/*
 * uio extensions
 *
 * PSARC 2009/478: Copy Reduction Interfaces
 */
typedef enum xuio_type {
	UIOTYPE_ASYNCIO,
	UIOTYPE_ZEROCOPY,
	UIOTYPE_PEEKSIZE
} xuio_type_t;

typedef struct xuio {
	uio_t xu_uio;		/* Embedded UIO structure */

	/* Extended uio fields */
	enum xuio_type xu_type;	/* What kind of uio structure? */
	union {
		/* Async I/O Support, intend to replace uioa_t. */
		struct {
			uint32_t xu_a_state;	/* state of async i/o */
			/* bytes that have been uioamove()ed */
			ssize_t xu_a_mbytes;
			uioa_page_t *xu_a_lcur;	/* pointer into uioa_locked[] */
			/* pointer into lcur->uioa_ppp[] */
			void **xu_a_lppp;
			void *xu_a_hwst[4];	/* opaque hardware state */
			/* Per iov locked pages */
			uioa_page_t xu_a_locked[UIOA_IOV_MAX];
		} xu_aio;

		/*
		 * Copy Reduction Support -- facilate loaning / returning of
		 * filesystem cache buffers.
		 */
		struct {
			int xu_zc_rw;	/* read or write buffer */
			void *xu_zc_priv;	/* fs specific */
		} xu_zc;

		/*
		 * Peek Size Support -- facilitate peeking at the size of a
		 * waiting message on a socket.
		 */
		struct {
			ssize_t xu_ps_size;	/* size of waiting msg */
			boolean_t xu_ps_set;	/* was size calculated? */
		} xu_ps;
	} xu_ext;
} xuio_t;

#define	XUIO_XUZC_PRIV(xuio)    xuio->xu_ext.xu_zc.xu_zc_priv
#define	XUIO_XUZC_RW(xuio)	xuio->xu_ext.xu_zc.xu_zc_rw

#define	UIOA_ALLOC	0x0001		/* allocated but not yet initialized */
#define	UIOA_INIT	0x0002		/* initialized but not yet enabled */
#define	UIOA_ENABLED	0x0004		/* enabled, asynch i/o active */
#define	UIOA_FINI	0x0008		/* finished waiting for uioafini() */

#define	UIOA_CLR	(~0x000F)	/* clear mutually exclusive bits */

#define	UIOA_POLL	0x0010		/* need dcopy_poll() */

#define	uio_loffset	_uio_offset._f
#if !defined(_LP64)
#define	uio_offset	_uio_offset._p._l
#else
#define	uio_offset	uio_loffset
#endif

#define	uio_llimit	_uio_limit._f
#if !defined(_LP64)
#define	uio_limit	_uio_limit._p._l
#else
#define	uio_limit	uio_llimit
#endif

/*
 * I/O direction.
 */
typedef enum uio_rw { UIO_READ, UIO_WRITE } uio_rw_t;

/*
 * uio_extflg: extended flags
 *
 * NOTE: This flag will be used in uiomove to determine if non-temporal
 * access, ie, access bypassing caches, should be used.  Filesystems that
 * don't initialize this field could experience suboptimal performance due to
 * the random data the field contains.
 *
 * NOTE: This flag is also used by uioasync callers to pass an extended
 * uio_t (uioa_t), to uioasync enabled consumers. Unlike above all
 * consumers of a uioa_t require the uio_extflg to be initialized.
 */
#define	UIO_COPY_DEFAULT	0x0000	/* no special options to copy */
#define	UIO_COPY_CACHED		0x0001	/* copy should not bypass caches */

#define	UIO_ASYNC		0x0002	/* uio_t is really a uioa_t */
#define	UIO_XUIO		0x0004	/* Structure is xuio_t */

/*
 * Global uioasync capability shadow state.
 */
typedef struct uioasync_s {
	boolean_t	enabled;	/* Is uioasync enabled? */
	size_t		mincnt;		/* Minimum byte count for use of */
} uioasync_t;

#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */

#if defined(_KERNEL) || defined(_FAKE_KERNEL)

int	uiomove(void *, size_t, enum uio_rw, uio_t *);
void	uio_prefaultpages(ssize_t, uio_t *);
int	uiocopy(void *, size_t, enum uio_rw, uio_t *, size_t *);
int	ureadc(int, uio_t *);	/* should be errno_t in future */
int	uwritec(struct uio *);
void	uioskip(uio_t *, size_t);
int	uiodup(uio_t *, uio_t *, iovec_t *, int);

int	uioamove(void *, size_t, enum uio_rw, uioa_t *);
int	uioainit(uio_t *, uioa_t *);
int	uioafini(uio_t *, uioa_t *);
extern	uioasync_t uioasync;

#else	/* defined(_KERNEL) */

extern ssize_t readv(int, const struct iovec *, int);
extern ssize_t writev(int, const struct iovec *, int);

/*
 * When in the large file compilation environment,
 * map preadv/pwritev to their 64 bit offset versions
 */
#if !defined(_LP64) && _FILE_OFFSET_BITS == 64
#ifdef __PRAGMA_REDEFINE_EXTNAME
#pragma	redefine_extname	preadv	preadv64
#pragma	redefine_extname	pwritev	pwritev64
#else /* __PRAGMA_REDEFINE_EXTNAME */
#define	preadv	preadv64
#define	pwritev	pwritev64
#endif /* __PRAGMA_REDEFINE_EXTNAME */
#endif /* !_LP64 && _FILE_OFFSET_BITS == 64 */

/* In the LP64 compilation environment, the APIs are already large file */
#if defined(_LP64) && defined(_LARGEFILE64_SOURCE)
#ifdef  __PRAGMA_REDEFINE_EXTNAME
#pragma	redefine_extname	preadv64	preadv
#pragma	redefine_extname	pwritev64	pwritev
#else   /* __PRAGMA_REDEFINE_EXTNAME */
#define	preadv64	preadv
#define	pwritev64	pwritev
#endif  /* __PRAGMA_REDEFINE_EXTNAME */
#endif  /* _LP64 && _LARGEFILE64_SOURCE */

extern ssize_t preadv(int, const struct iovec *, int, off_t);
extern ssize_t pwritev(int, const struct iovec *, int, off_t);

/*
 * preadv64 and pwritev64 should be defined when:
 * - Using the transitional compilation environment, and not
 *     the large file compilation environment.
 */
#if defined(_LARGEFILE64_SOURCE) && !((_FILE_OFFSET_BITS == 64) && \
	!defined(__PRAGMA_REDEFINE_EXTNAME))
extern ssize_t preadv64(int, const struct iovec *, int, off64_t);
extern ssize_t pwritev64(int, const struct iovec *, int, off64_t);
#endif /* _LARGEFILE64_SOURCE */

#endif	/* defined(_KERNEL) */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_UIO_H */