xref: /titanic_51/usr/src/lib/libfakekernel/common/uio.c (revision a90cf9f29973990687fa61de9f1f6ea22e924e40)
1b819cea2SGordon Ross /*
2b819cea2SGordon Ross  * This file and its contents are supplied under the terms of the
3b819cea2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4b819cea2SGordon Ross  * You may only use this file in accordance with the terms of version
5b819cea2SGordon Ross  * 1.0 of the CDDL.
6b819cea2SGordon Ross  *
7b819cea2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8b819cea2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9b819cea2SGordon Ross  * http://www.illumos.org/license/CDDL.
10b819cea2SGordon Ross  */
11b819cea2SGordon Ross 
12b819cea2SGordon Ross /*
13*a90cf9f2SGordon Ross  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
14b819cea2SGordon Ross  */
15b819cea2SGordon Ross 
16b819cea2SGordon Ross #include <sys/types.h>
17b819cea2SGordon Ross #include <sys/sysmacros.h>
18b819cea2SGordon Ross #include <sys/param.h>
19b819cea2SGordon Ross #include <sys/systm.h>
20b819cea2SGordon Ross #include <sys/uio.h>
21b819cea2SGordon Ross #include <sys/errno.h>
22b819cea2SGordon Ross 
23b819cea2SGordon Ross /*
24b819cea2SGordon Ross  * Move "n" bytes at byte address "p"; "rw" indicates the direction
25b819cea2SGordon Ross  * of the move, and the I/O parameters are provided in "uio", which is
26b819cea2SGordon Ross  * update to reflect the data which was moved.  Returns 0 on success or
27b819cea2SGordon Ross  * a non-zero errno on failure.
28b819cea2SGordon Ross  */
29b819cea2SGordon Ross int
30b819cea2SGordon Ross uiomove(void *p, size_t n, enum uio_rw rw, struct uio *uio)
31b819cea2SGordon Ross {
32b819cea2SGordon Ross 	struct iovec *iov;
33b819cea2SGordon Ross 	ulong_t cnt;
34b819cea2SGordon Ross 
35b819cea2SGordon Ross 	while (n && uio->uio_resid) {
36b819cea2SGordon Ross 		iov = uio->uio_iov;
37b819cea2SGordon Ross 		cnt = MIN(iov->iov_len, n);
38b819cea2SGordon Ross 		if (cnt == 0L) {
39b819cea2SGordon Ross 			uio->uio_iov++;
40b819cea2SGordon Ross 			uio->uio_iovcnt--;
41b819cea2SGordon Ross 			continue;
42b819cea2SGordon Ross 		}
43b819cea2SGordon Ross 		switch (uio->uio_segflg) {
44b819cea2SGordon Ross 
45b819cea2SGordon Ross 		case UIO_USERSPACE:
46b819cea2SGordon Ross 		case UIO_USERISPACE:
47b819cea2SGordon Ross 			return (EINVAL);
48b819cea2SGordon Ross 
49b819cea2SGordon Ross 		case UIO_SYSSPACE:
50b819cea2SGordon Ross 			if (rw == UIO_READ)
51b819cea2SGordon Ross 				bcopy(p, iov->iov_base, cnt);
52b819cea2SGordon Ross 			else
53b819cea2SGordon Ross 				bcopy(iov->iov_base, p, cnt);
54b819cea2SGordon Ross 			break;
55b819cea2SGordon Ross 		}
56b819cea2SGordon Ross 		iov->iov_base += cnt;
57b819cea2SGordon Ross 		iov->iov_len -= cnt;
58b819cea2SGordon Ross 		uio->uio_resid -= cnt;
59b819cea2SGordon Ross 		uio->uio_loffset += cnt;
60b819cea2SGordon Ross 		p = (caddr_t)p + cnt;
61b819cea2SGordon Ross 		n -= cnt;
62b819cea2SGordon Ross 	}
63b819cea2SGordon Ross 	return (0);
64b819cea2SGordon Ross }
65*a90cf9f2SGordon Ross 
66*a90cf9f2SGordon Ross /*
67*a90cf9f2SGordon Ross  * Drop the next n chars out of *uiop.
68*a90cf9f2SGordon Ross  */
69*a90cf9f2SGordon Ross void
70*a90cf9f2SGordon Ross uioskip(uio_t *uiop, size_t n)
71*a90cf9f2SGordon Ross {
72*a90cf9f2SGordon Ross 	if (n > uiop->uio_resid)
73*a90cf9f2SGordon Ross 		return;
74*a90cf9f2SGordon Ross 	while (n != 0) {
75*a90cf9f2SGordon Ross 		iovec_t	*iovp = uiop->uio_iov;
76*a90cf9f2SGordon Ross 		size_t	niovb = MIN(iovp->iov_len, n);
77*a90cf9f2SGordon Ross 
78*a90cf9f2SGordon Ross 		if (niovb == 0) {
79*a90cf9f2SGordon Ross 			uiop->uio_iov++;
80*a90cf9f2SGordon Ross 			uiop->uio_iovcnt--;
81*a90cf9f2SGordon Ross 			continue;
82*a90cf9f2SGordon Ross 		}
83*a90cf9f2SGordon Ross 		iovp->iov_base += niovb;
84*a90cf9f2SGordon Ross 		uiop->uio_loffset += niovb;
85*a90cf9f2SGordon Ross 		iovp->iov_len -= niovb;
86*a90cf9f2SGordon Ross 		uiop->uio_resid -= niovb;
87*a90cf9f2SGordon Ross 		n -= niovb;
88*a90cf9f2SGordon Ross 	}
89*a90cf9f2SGordon Ross }
90