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