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