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