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