1/* $NetBSD: uio.h,v 1.12 2018/11/30 09:53:40 hannken Exp $ */ 2 3/*- 4 * Copyright (c) 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/*- 33 * Copyright (c) 2007 Pawel Jakub Dawidek <pjd@FreeBSD.org> 34 * All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 * 57 * $FreeBSD: head/sys/cddl/compat/opensolaris/sys/uio.h 219089 2011-02-27 19:41:40Z pjd $ 58 */ 59 60#ifndef _OPENSOLARIS_SYS_UIO_H_ 61#define _OPENSOLARIS_SYS_UIO_H_ 62 63#include_next <sys/uio.h> 64#include <sys/debug.h> 65 66#ifndef _KERNEL 67#include <assert.h> 68#include <string.h> 69 70#define FOF_OFFSET 1 /* Use the offset in uio argument */ 71 72struct uio { 73 struct iovec *uio_iov; 74 int uio_iovcnt; 75 off_t uio_offset; 76 int uio_resid; 77 enum uio_seg uio_segflg; 78 enum uio_rw uio_rw; 79 void *uio_td; 80}; 81#endif 82 83struct xuio { 84 struct uio xu_uio; 85 int xuio_rw; 86 void *xuio_priv; 87}; 88 89#define XUIO_XUZC_PRIV(xuio) ((xuio)->xuio_priv) 90#define XUIO_XUZC_RW(xuio) ((xuio)->xuio_rw) 91 92typedef struct uio uio_t; 93typedef struct xuio xuio_t; 94typedef struct iovec iovec_t; 95 96typedef enum uio_seg uio_seg_t; 97 98#define uio_loffset uio_offset 99 100int uiomove(void *, size_t, struct uio *); 101 102static __inline int 103zfs_uiomove(void *cp, size_t n, enum uio_rw dir, uio_t *uio) 104{ 105 106 assert(uio->uio_rw == dir); 107 return (uiomove(cp, n, uio)); 108} 109 110#define ZFS_MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b)) 111 112static __inline int 113zfs_uiocopy(void *cp, size_t n, enum uio_rw dir, uio_t *uio, size_t *cbytes) 114{ 115 uio_t auio; 116 struct iovec aiov; 117 size_t cnt; 118 int i, error; 119 120 *cbytes = 0; 121 memcpy(&auio, uio, sizeof(*uio)); 122 for (i = 0; i < uio->uio_iovcnt && n > 0; i++) { 123 auio.uio_iov = &aiov; 124 auio.uio_iovcnt = 1; 125 aiov = uio->uio_iov[i]; 126 cnt = ZFS_MIN(aiov.iov_len, n); 127 if (cnt == 0) 128 continue; 129 error = uiomove(cp, cnt, &auio); 130 if (error) 131 return error; 132 cp = (char *)cp + cnt; 133 n -= cnt; 134 *cbytes += cnt; 135 } 136 137 return 0; 138} 139 140static __inline void 141zfs_uioskip(uio_t *uiop, size_t n) 142{ 143 if (n > (size_t)uiop->uio_resid) 144 return; 145 while (n != 0) { 146 iovec_t *iovp = uiop->uio_iov; 147 size_t niovb = ZFS_MIN(iovp->iov_len, n); 148 149 if (niovb == 0) { 150 uiop->uio_iov++; 151 uiop->uio_iovcnt--; 152 continue; 153 } 154 iovp->iov_base = (char *)iovp->iov_base + niovb; 155 uiop->uio_offset += (off_t)niovb; 156 iovp->iov_len -= niovb; 157 uiop->uio_resid -= (int)niovb; 158 n -= niovb; 159 } 160 161} 162 163#define uiomove(cp, n, dir, uio) zfs_uiomove((cp), (n), (dir), (uio)) 164#define uiocopy(cp, n, dir, uio, cbytes) zfs_uiocopy((cp), (n), (dir), (uio), (cbytes)) 165#define uioskip(uio, size) zfs_uioskip((uio), (size)) 166 167#endif /* !_OPENSOLARIS_SYS_UIO_H_ */ 168