diff --git a/include/os/freebsd/spl/sys/uio.h b/include/os/freebsd/spl/sys/uio.h index fe5e24b99d1..2b4357a30b0 100644 --- a/include/os/freebsd/spl/sys/uio.h +++ b/include/os/freebsd/spl/sys/uio.h @@ -74,4 +74,37 @@ zfs_uiomove(void *cp, size_t n, enum uio_rw dir, uio_t *uio) int uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes); void uioskip(uio_t *uiop, size_t n); +#define uio_segflg(uio) (uio)->uio_segflg +#define uio_offset(uio) (uio)->uio_loffset +#define uio_resid(uio) (uio)->uio_resid +#define uio_iovcnt(uio) (uio)->uio_iovcnt +#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len +#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base + +static inline void +uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len) +{ + *base = uio_iovbase(uio, idx); + *len = uio_iovlen(uio, idx); +} + +static inline void +uio_advance(uio_t *uio, size_t size) +{ + uio->uio_resid -= size; + uio->uio_loffset += size; +} + +static inline offset_t +uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx) +{ + *vec_idx = 0; + while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) { + off -= uio_iovlen(uio, *vec_idx); + (*vec_idx)++; + } + + return (off); +} + #endif /* !_OPENSOLARIS_SYS_UIO_H_ */ diff --git a/include/os/linux/spl/sys/uio.h b/include/os/linux/spl/sys/uio.h index e51152b8898..0e631d6779a 100644 --- a/include/os/linux/spl/sys/uio.h +++ b/include/os/linux/spl/sys/uio.h @@ -108,4 +108,37 @@ typedef struct xuio { #define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv #define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw +#define uio_segflg(uio) (uio)->uio_segflg +#define uio_offset(uio) (uio)->uio_loffset +#define uio_resid(uio) (uio)->uio_resid +#define uio_iovcnt(uio) (uio)->uio_iovcnt +#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len +#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base + +static inline void +uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len) +{ + *base = uio_iovbase(uio, idx); + *len = uio_iovlen(uio, idx); +} + +static inline void +uio_advance(uio_t *uio, size_t size) +{ + uio->uio_resid -= size; + uio->uio_loffset += size; +} + +static inline offset_t +uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx) +{ + *vec_idx = 0; + while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) { + off -= uio_iovlen(uio, *vec_idx); + (*vec_idx)++; + } + + return (off); +} + #endif /* SPL_UIO_H */ diff --git a/lib/libspl/include/os/freebsd/sys/Makefile.am b/lib/libspl/include/os/freebsd/sys/Makefile.am index 896c9387129..1f85b208e34 100644 --- a/lib/libspl/include/os/freebsd/sys/Makefile.am +++ b/lib/libspl/include/os/freebsd/sys/Makefile.am @@ -7,6 +7,5 @@ libspl_HEADERS = \ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/param.h \ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/stat.h \ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/sysmacros.h \ - $(top_srcdir)/lib/libspl/include/os/freebsd/sys/uio.h \ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/vfs.h \ $(top_srcdir)/lib/libspl/include/os/freebsd/sys/zfs_context_os.h diff --git a/lib/libspl/include/os/freebsd/sys/uio.h b/lib/libspl/include/os/freebsd/sys/uio.h deleted file mode 100644 index d978b6ad077..00000000000 --- a/lib/libspl/include/os/freebsd/sys/uio.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - -/* - * University Copyright- Copyright (c) 1982, 1986, 1988 - * The Regents of the University of California - * All Rights Reserved - * - * University Acknowledgment- Portions of this document are derived from - * software developed by the University of California, Berkeley, and its - * contributors. - */ - -#ifndef _LIBSPL_SYS_UIO_H -#define _LIBSPL_SYS_UIO_H - -#include_next - -typedef struct iovec iovec_t; -typedef enum uio_seg uio_seg_t; - -typedef struct uio { - struct iovec *uio_iov; /* pointer to array of iovecs */ - int uio_iovcnt; /* number of iovecs */ - offset_t uio_loffset; /* file offset */ - uio_seg_t uio_segflg; /* address space (kernel or user) */ - uint16_t uio_fmode; /* file mode flags */ - uint16_t uio_extflg; /* extended flags */ - offset_t uio_limit; /* u-limit (maximum byte offset) */ - ssize_t uio_resid; /* residual count */ -} uio_t; - -typedef enum xuio_type { - UIOTYPE_ASYNCIO, - UIOTYPE_ZEROCOPY, -} xuio_type_t; - -#define UIOA_IOV_MAX 16 - -typedef struct uioa_page_s { /* locked uio_iov state */ - int uioa_pfncnt; /* count of pfn_t(s) in *uioa_ppp */ - void **uioa_ppp; /* page_t or pfn_t array */ - caddr_t uioa_base; /* address base */ - size_t uioa_len; /* span length */ -} uioa_page_t; - -typedef struct xuio { - uio_t xu_uio; /* embedded UIO structure */ - - /* Extended uio fields */ - enum xuio_type xu_type; /* uio type */ - union { - struct { - uint32_t xu_a_state; /* state of async i/o */ - ssize_t xu_a_mbytes; /* bytes moved */ - uioa_page_t *xu_a_lcur; /* uioa_locked[] pointer */ - void **xu_a_lppp; /* lcur->uioa_pppp[] pointer */ - void *xu_a_hwst[4]; /* opaque hardware state */ - uioa_page_t xu_a_locked[UIOA_IOV_MAX]; - } xu_aio; - - struct { - int xu_zc_rw; /* read or write buffer */ - void *xu_zc_priv; /* fs specific */ - } xu_zc; - } xu_ext; -} xuio_t; - -#define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv -#define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw - -#endif /* _SYS_UIO_H */ diff --git a/lib/libspl/include/os/linux/sys/Makefile.am b/lib/libspl/include/os/linux/sys/Makefile.am index 49e9f730efe..b7019fc37ef 100644 --- a/lib/libspl/include/os/linux/sys/Makefile.am +++ b/lib/libspl/include/os/linux/sys/Makefile.am @@ -7,5 +7,4 @@ libspl_HEADERS = \ $(top_srcdir)/lib/libspl/include/os/linux/sys/param.h \ $(top_srcdir)/lib/libspl/include/os/linux/sys/stat.h \ $(top_srcdir)/lib/libspl/include/os/linux/sys/sysmacros.h \ - $(top_srcdir)/lib/libspl/include/os/linux/sys/uio.h \ $(top_srcdir)/lib/libspl/include/os/linux/sys/zfs_context_os.h diff --git a/lib/libspl/include/sys/Makefile.am b/lib/libspl/include/sys/Makefile.am index 8f9c2fa9917..5125b8ac3ba 100644 --- a/lib/libspl/include/sys/Makefile.am +++ b/lib/libspl/include/sys/Makefile.am @@ -39,6 +39,7 @@ libspl_HEADERS = \ $(top_srcdir)/lib/libspl/include/sys/types32.h \ $(top_srcdir)/lib/libspl/include/sys/types.h \ $(top_srcdir)/lib/libspl/include/sys/tzfile.h \ + $(top_srcdir)/lib/libspl/include/sys/uio.h \ $(top_srcdir)/lib/libspl/include/sys/va_list.h \ $(top_srcdir)/lib/libspl/include/sys/varargs.h \ $(top_srcdir)/lib/libspl/include/sys/vnode.h \ diff --git a/lib/libspl/include/os/linux/sys/uio.h b/lib/libspl/include/sys/uio.h similarity index 73% rename from lib/libspl/include/os/linux/sys/uio.h rename to lib/libspl/include/sys/uio.h index 0b85af66dcc..6d892dd3e20 100644 --- a/lib/libspl/include/os/linux/sys/uio.h +++ b/lib/libspl/include/sys/uio.h @@ -43,9 +43,14 @@ #include #include_next +#ifdef __APPLE__ +#include +#endif + #include typedef struct iovec iovec_t; +#if defined(__linux__) || defined(__APPLE__) typedef enum uio_rw { UIO_READ = 0, UIO_WRITE = 1, @@ -57,14 +62,18 @@ typedef enum uio_seg { UIO_USERISPACE = 2, } uio_seg_t; +#elif defined(__FreeBSD__) +typedef enum uio_seg uio_seg_t; +#endif + typedef struct uio { struct iovec *uio_iov; /* pointer to array of iovecs */ int uio_iovcnt; /* number of iovecs */ - loff_t uio_loffset; /* file offset */ + offset_t uio_loffset; /* file offset */ uio_seg_t uio_segflg; /* address space (kernel or user) */ uint16_t uio_fmode; /* file mode flags */ uint16_t uio_extflg; /* extended flags */ - loff_t uio_limit; /* u-limit (maximum byte offset) */ + offset_t uio_limit; /* u-limit (maximum byte offset) */ ssize_t uio_resid; /* residual count */ } uio_t; @@ -107,4 +116,37 @@ typedef struct xuio { #define XUIO_XUZC_PRIV(xuio) xuio->xu_ext.xu_zc.xu_zc_priv #define XUIO_XUZC_RW(xuio) xuio->xu_ext.xu_zc.xu_zc_rw +#define uio_segflg(uio) (uio)->uio_segflg +#define uio_offset(uio) (uio)->uio_loffset +#define uio_resid(uio) (uio)->uio_resid +#define uio_iovcnt(uio) (uio)->uio_iovcnt +#define uio_iovlen(uio, idx) (uio)->uio_iov[(idx)].iov_len +#define uio_iovbase(uio, idx) (uio)->uio_iov[(idx)].iov_base + +static inline void +uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len) +{ + *base = uio_iovbase(uio, idx); + *len = uio_iovlen(uio, idx); +} + +static inline void +uio_advance(uio_t *uio, size_t size) +{ + uio->uio_resid -= size; + uio->uio_loffset += size; +} + +static inline offset_t +uio_index_at_offset(uio_t *uio, offset_t off, uint_t *vec_idx) +{ + *vec_idx = 0; + while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) { + off -= uio_iovlen(uio, *vec_idx); + (*vec_idx)++; + } + + return (off); +} + #endif /* _SYS_UIO_H */ diff --git a/module/icp/algs/modes/modes.c b/module/icp/algs/modes/modes.c index 1d33c426881..f07876a478e 100644 --- a/module/icp/algs/modes/modes.c +++ b/module/icp/algs/modes/modes.c @@ -44,16 +44,13 @@ crypto_init_ptrs(crypto_data_t *out, void **iov_or_mp, offset_t *current_offset) case CRYPTO_DATA_UIO: { uio_t *uiop = out->cd_uio; - uintptr_t vec_idx; + uint_t vec_idx; offset = out->cd_offset; - for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && - offset >= uiop->uio_iov[vec_idx].iov_len; - offset -= uiop->uio_iov[vec_idx++].iov_len) - ; + offset = uio_index_at_offset(uiop, offset, &vec_idx); *current_offset = offset; - *iov_or_mp = (void *)vec_idx; + *iov_or_mp = (void *)(uintptr_t)vec_idx; break; } } /* end switch */ @@ -89,33 +86,34 @@ crypto_get_ptrs(crypto_data_t *out, void **iov_or_mp, offset_t *current_offset, case CRYPTO_DATA_UIO: { uio_t *uio = out->cd_uio; - iovec_t *iov; offset_t offset; - uintptr_t vec_idx; + uint_t vec_idx; uint8_t *p; + uint64_t iov_len; + void *iov_base; offset = *current_offset; vec_idx = (uintptr_t)(*iov_or_mp); - iov = (iovec_t *)&uio->uio_iov[vec_idx]; - p = (uint8_t *)iov->iov_base + offset; + uio_iov_at_index(uio, vec_idx, &iov_base, &iov_len); + p = (uint8_t *)iov_base + offset; *out_data_1 = p; - if (offset + amt <= iov->iov_len) { + if (offset + amt <= iov_len) { /* can fit one block into this iov */ *out_data_1_len = amt; *out_data_2 = NULL; *current_offset = offset + amt; } else { /* one block spans two iovecs */ - *out_data_1_len = iov->iov_len - offset; - if (vec_idx == uio->uio_iovcnt) + *out_data_1_len = iov_len - offset; + if (vec_idx == uio_iovcnt(uio)) return; vec_idx++; - iov = (iovec_t *)&uio->uio_iov[vec_idx]; - *out_data_2 = (uint8_t *)iov->iov_base; + uio_iov_at_index(uio, vec_idx, &iov_base, &iov_len); + *out_data_2 = (uint8_t *)iov_base; *current_offset = amt - *out_data_1_len; } - *iov_or_mp = (void *)vec_idx; + *iov_or_mp = (void *)(uintptr_t)vec_idx; break; } } /* end switch */ diff --git a/module/icp/core/kcf_prov_lib.c b/module/icp/core/kcf_prov_lib.c index 6a60eb3db44..905ef665733 100644 --- a/module/icp/core/kcf_prov_lib.c +++ b/module/icp/core/kcf_prov_lib.c @@ -48,7 +48,7 @@ crypto_uio_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, uchar_t *datap; ASSERT(data->cd_format == CRYPTO_DATA_UIO); - if (uiop->uio_segflg != UIO_SYSSPACE) { + if (uio_segflg(uiop) != UIO_SYSSPACE) { return (CRYPTO_ARGUMENTS_BAD); } @@ -56,12 +56,9 @@ crypto_uio_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, * Jump to the first iovec containing data to be * processed. */ - for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && - offset >= uiop->uio_iov[vec_idx].iov_len; - offset -= uiop->uio_iov[vec_idx++].iov_len) - ; + offset = uio_index_at_offset(uiop, offset, &vec_idx); - if (vec_idx == uiop->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(uiop) && length > 0) { /* * The caller specified an offset that is larger than * the total size of the buffers it provided. @@ -69,12 +66,11 @@ crypto_uio_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, return (CRYPTO_DATA_LEN_RANGE); } - while (vec_idx < uiop->uio_iovcnt && length > 0) { - cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(uiop) && length > 0) { + cur_len = MIN(uio_iovlen(uiop, vec_idx) - offset, length); - datap = (uchar_t *)(uiop->uio_iov[vec_idx].iov_base + - offset); + datap = (uchar_t *)(uio_iovbase(uiop, vec_idx) + offset); switch (cmd) { case COPY_FROM_DATA: bcopy(datap, buf, cur_len); @@ -101,7 +97,7 @@ crypto_uio_data(crypto_data_t *data, uchar_t *buf, int len, cmd_type_t cmd, offset = 0; } - if (vec_idx == uiop->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(uiop) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed. @@ -182,7 +178,7 @@ crypto_update_uio(void *ctx, crypto_data_t *input, crypto_data_t *output, &common_ctx->cc_iv[0]); } - if (input->cd_uio->uio_segflg != UIO_SYSSPACE) { + if (uio_segflg(input->cd_uio) != UIO_SYSSPACE) { return (CRYPTO_ARGUMENTS_BAD); } @@ -190,11 +186,8 @@ crypto_update_uio(void *ctx, crypto_data_t *input, crypto_data_t *output, * Jump to the first iovec containing data to be * processed. */ - for (vec_idx = 0; vec_idx < uiop->uio_iovcnt && - offset >= uiop->uio_iov[vec_idx].iov_len; - offset -= uiop->uio_iov[vec_idx++].iov_len) - ; - if (vec_idx == uiop->uio_iovcnt && length > 0) { + offset = uio_index_at_offset(uiop, offset, &vec_idx); + if (vec_idx == uio_iovcnt(uiop) && length > 0) { /* * The caller specified an offset that is larger than the * total size of the buffers it provided. @@ -205,11 +198,11 @@ crypto_update_uio(void *ctx, crypto_data_t *input, crypto_data_t *output, /* * Now process the iovecs. */ - while (vec_idx < uiop->uio_iovcnt && length > 0) { - cur_len = MIN(uiop->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(uiop) && length > 0) { + cur_len = MIN(uio_iovlen(uiop, vec_idx) - offset, length); - int rv = (cipher)(ctx, uiop->uio_iov[vec_idx].iov_base + offset, + int rv = (cipher)(ctx, uio_iovbase(uiop, vec_idx) + offset, cur_len, output); if (rv != CRYPTO_SUCCESS) { @@ -220,7 +213,7 @@ crypto_update_uio(void *ctx, crypto_data_t *input, crypto_data_t *output, offset = 0; } - if (vec_idx == uiop->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(uiop) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. diff --git a/module/icp/io/sha1_mod.c b/module/icp/io/sha1_mod.c index e7c38542a79..d0b23cb7861 100644 --- a/module/icp/io/sha1_mod.c +++ b/module/icp/io/sha1_mod.c @@ -270,19 +270,15 @@ sha1_digest_update_uio(SHA1_CTX *sha1_ctx, crypto_data_t *data) size_t cur_len; /* we support only kernel buffer */ - if (data->cd_uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(data->cd_uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* * Jump to the first iovec containing data to be * digested. */ - while (vec_idx < data->cd_uio->uio_iovcnt && - offset >= data->cd_uio->uio_iov[vec_idx].iov_len) { - offset -= data->cd_uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == data->cd_uio->uio_iovcnt) { + offset = uio_index_at_offset(data->cd_uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(data->cd_uio)) { /* * The caller specified an offset that is larger than the * total size of the buffers it provided. @@ -293,12 +289,12 @@ sha1_digest_update_uio(SHA1_CTX *sha1_ctx, crypto_data_t *data) /* * Now do the digesting on the iovecs. */ - while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) { - cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(data->cd_uio) && length > 0) { + cur_len = MIN(uio_iovlen(data->cd_uio, vec_idx) - offset, length); SHA1Update(sha1_ctx, - (uint8_t *)data->cd_uio->uio_iov[vec_idx].iov_base + offset, + (uint8_t *)uio_iovbase(data->cd_uio, vec_idx) + offset, cur_len); length -= cur_len; @@ -306,7 +302,7 @@ sha1_digest_update_uio(SHA1_CTX *sha1_ctx, crypto_data_t *data) offset = 0; } - if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(data->cd_uio) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. @@ -333,19 +329,15 @@ sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest, uint_t vec_idx = 0; /* we support only kernel buffer */ - if (digest->cd_uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(digest->cd_uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* * Jump to the first iovec containing ptr to the digest to * be returned. */ - while (vec_idx < digest->cd_uio->uio_iovcnt && - offset >= digest->cd_uio->uio_iov[vec_idx].iov_len) { - offset -= digest->cd_uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == digest->cd_uio->uio_iovcnt) { + offset = uio_index_at_offset(digest->cd_uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(digest->cd_uio)) { /* * The caller specified an offset that is * larger than the total size of the buffers @@ -355,7 +347,7 @@ sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest, } if (offset + digest_len <= - digest->cd_uio->uio_iov[vec_idx].iov_len) { + uio_iovlen(digest->cd_uio, vec_idx)) { /* * The computed SHA1 digest will fit in the current * iovec. @@ -367,12 +359,12 @@ sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest, * the user only what was requested. */ SHA1Final(digest_scratch, sha1_ctx); - bcopy(digest_scratch, (uchar_t *)digest-> - cd_uio->uio_iov[vec_idx].iov_base + offset, + bcopy(digest_scratch, (uchar_t *)uio_iovbase(digest-> + cd_uio, vec_idx) + offset, digest_len); } else { - SHA1Final((uchar_t *)digest-> - cd_uio->uio_iov[vec_idx].iov_base + offset, + SHA1Final((uchar_t *)uio_iovbase(digest-> + cd_uio, vec_idx) + offset, sha1_ctx); } } else { @@ -389,11 +381,11 @@ sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest, SHA1Final(digest_tmp, sha1_ctx); - while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) { - cur_len = MIN(digest->cd_uio->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(digest->cd_uio) && length > 0) { + cur_len = MIN(uio_iovlen(digest->cd_uio, vec_idx) - offset, length); bcopy(digest_tmp + scratch_offset, - digest->cd_uio->uio_iov[vec_idx].iov_base + offset, + uio_iovbase(digest->cd_uio, vec_idx) + offset, cur_len); length -= cur_len; @@ -402,7 +394,7 @@ sha1_digest_final_uio(SHA1_CTX *sha1_ctx, crypto_data_t *digest, offset = 0; } - if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(digest->cd_uio) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. @@ -1103,16 +1095,12 @@ sha1_mac_verify_atomic(crypto_provider_handle_t provider, size_t cur_len; /* we support only kernel buffer */ - if (mac->cd_uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(mac->cd_uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* jump to the first iovec containing the expected digest */ - while (vec_idx < mac->cd_uio->uio_iovcnt && - offset >= mac->cd_uio->uio_iov[vec_idx].iov_len) { - offset -= mac->cd_uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == mac->cd_uio->uio_iovcnt) { + offset = uio_index_at_offset(mac->cd_uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(mac->cd_uio)) { /* * The caller specified an offset that is * larger than the total size of the buffers @@ -1123,12 +1111,12 @@ sha1_mac_verify_atomic(crypto_provider_handle_t provider, } /* do the comparison of computed digest vs specified one */ - while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) { - cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(mac->cd_uio) && length > 0) { + cur_len = MIN(uio_iovlen(mac->cd_uio, vec_idx) - offset, length); if (bcmp(digest + scratch_offset, - mac->cd_uio->uio_iov[vec_idx].iov_base + offset, + uio_iovbase(mac->cd_uio, vec_idx) + offset, cur_len) != 0) { ret = CRYPTO_INVALID_MAC; break; diff --git a/module/icp/io/sha2_mod.c b/module/icp/io/sha2_mod.c index 3254f559755..a4a5c6041dd 100644 --- a/module/icp/io/sha2_mod.c +++ b/module/icp/io/sha2_mod.c @@ -296,19 +296,15 @@ sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data) size_t cur_len; /* we support only kernel buffer */ - if (data->cd_uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(data->cd_uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* * Jump to the first iovec containing data to be * digested. */ - while (vec_idx < data->cd_uio->uio_iovcnt && - offset >= data->cd_uio->uio_iov[vec_idx].iov_len) { - offset -= data->cd_uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == data->cd_uio->uio_iovcnt) { + offset = uio_index_at_offset(data->cd_uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(data->cd_uio)) { /* * The caller specified an offset that is larger than the * total size of the buffers it provided. @@ -319,18 +315,18 @@ sha2_digest_update_uio(SHA2_CTX *sha2_ctx, crypto_data_t *data) /* * Now do the digesting on the iovecs. */ - while (vec_idx < data->cd_uio->uio_iovcnt && length > 0) { - cur_len = MIN(data->cd_uio->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(data->cd_uio) && length > 0) { + cur_len = MIN(uio_iovlen(data->cd_uio, vec_idx) - offset, length); - SHA2Update(sha2_ctx, (uint8_t *)data->cd_uio-> - uio_iov[vec_idx].iov_base + offset, cur_len); + SHA2Update(sha2_ctx, (uint8_t *)uio_iovbase(data->cd_uio, + vec_idx) + offset, cur_len); length -= cur_len; vec_idx++; offset = 0; } - if (vec_idx == data->cd_uio->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(data->cd_uio) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. @@ -357,19 +353,15 @@ sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest, uint_t vec_idx = 0; /* we support only kernel buffer */ - if (digest->cd_uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(digest->cd_uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* * Jump to the first iovec containing ptr to the digest to * be returned. */ - while (vec_idx < digest->cd_uio->uio_iovcnt && - offset >= digest->cd_uio->uio_iov[vec_idx].iov_len) { - offset -= digest->cd_uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == digest->cd_uio->uio_iovcnt) { + offset = uio_index_at_offset(digest->cd_uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(digest->cd_uio)) { /* * The caller specified an offset that is * larger than the total size of the buffers @@ -379,7 +371,7 @@ sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest, } if (offset + digest_len <= - digest->cd_uio->uio_iov[vec_idx].iov_len) { + uio_iovlen(digest->cd_uio, vec_idx)) { /* * The computed SHA2 digest will fit in the current * iovec. @@ -395,12 +387,12 @@ sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest, */ SHA2Final(digest_scratch, sha2_ctx); - bcopy(digest_scratch, (uchar_t *)digest-> - cd_uio->uio_iov[vec_idx].iov_base + offset, + bcopy(digest_scratch, (uchar_t *)uio_iovbase(digest-> + cd_uio, vec_idx) + offset, digest_len); } else { - SHA2Final((uchar_t *)digest-> - cd_uio->uio_iov[vec_idx].iov_base + offset, + SHA2Final((uchar_t *)uio_iovbase(digest-> + cd_uio, vec_idx) + offset, sha2_ctx); } @@ -418,12 +410,12 @@ sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest, SHA2Final(digest_tmp, sha2_ctx); - while (vec_idx < digest->cd_uio->uio_iovcnt && length > 0) { + while (vec_idx < uio_iovcnt(digest->cd_uio) && length > 0) { cur_len = - MIN(digest->cd_uio->uio_iov[vec_idx].iov_len - + MIN(uio_iovlen(digest->cd_uio, vec_idx) - offset, length); bcopy(digest_tmp + scratch_offset, - digest->cd_uio->uio_iov[vec_idx].iov_base + offset, + uio_iovbase(digest->cd_uio, vec_idx) + offset, cur_len); length -= cur_len; @@ -432,7 +424,7 @@ sha2_digest_final_uio(SHA2_CTX *sha2_ctx, crypto_data_t *digest, offset = 0; } - if (vec_idx == digest->cd_uio->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(digest->cd_uio) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. @@ -1259,16 +1251,12 @@ sha2_mac_verify_atomic(crypto_provider_handle_t provider, size_t cur_len; /* we support only kernel buffer */ - if (mac->cd_uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(mac->cd_uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* jump to the first iovec containing the expected digest */ - while (vec_idx < mac->cd_uio->uio_iovcnt && - offset >= mac->cd_uio->uio_iov[vec_idx].iov_len) { - offset -= mac->cd_uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == mac->cd_uio->uio_iovcnt) { + offset = uio_index_at_offset(mac->cd_uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(mac->cd_uio)) { /* * The caller specified an offset that is * larger than the total size of the buffers @@ -1279,12 +1267,12 @@ sha2_mac_verify_atomic(crypto_provider_handle_t provider, } /* do the comparison of computed digest vs specified one */ - while (vec_idx < mac->cd_uio->uio_iovcnt && length > 0) { - cur_len = MIN(mac->cd_uio->uio_iov[vec_idx].iov_len - + while (vec_idx < uio_iovcnt(mac->cd_uio) && length > 0) { + cur_len = MIN(uio_iovlen(mac->cd_uio, vec_idx) - offset, length); if (bcmp(digest + scratch_offset, - mac->cd_uio->uio_iov[vec_idx].iov_base + offset, + uio_iovbase(mac->cd_uio, vec_idx) + offset, cur_len) != 0) { ret = CRYPTO_INVALID_MAC; break; diff --git a/module/icp/io/skein_mod.c b/module/icp/io/skein_mod.c index afd7f568065..621fa615818 100644 --- a/module/icp/io/skein_mod.c +++ b/module/icp/io/skein_mod.c @@ -271,22 +271,18 @@ skein_digest_update_uio(skein_ctx_t *ctx, const crypto_data_t *data) size_t length = data->cd_length; uint_t vec_idx = 0; size_t cur_len; - const uio_t *uio = data->cd_uio; + uio_t *uio = data->cd_uio; /* we support only kernel buffer */ - if (uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* * Jump to the first iovec containing data to be * digested. */ - while (vec_idx < uio->uio_iovcnt && - offset >= uio->uio_iov[vec_idx].iov_len) { - offset -= uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == uio->uio_iovcnt) { + offset = uio_index_at_offset(uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(uio)) { /* * The caller specified an offset that is larger than the * total size of the buffers it provided. @@ -297,16 +293,16 @@ skein_digest_update_uio(skein_ctx_t *ctx, const crypto_data_t *data) /* * Now do the digesting on the iovecs. */ - while (vec_idx < uio->uio_iovcnt && length > 0) { - cur_len = MIN(uio->uio_iov[vec_idx].iov_len - offset, length); - SKEIN_OP(ctx, Update, (uint8_t *)uio->uio_iov[vec_idx].iov_base + while (vec_idx < uio_iovcnt(uio) && length > 0) { + cur_len = MIN(uio_iovlen(uio, vec_idx) - offset, length); + SKEIN_OP(ctx, Update, (uint8_t *)uio_iovbase(uio, vec_idx) + offset, cur_len); length -= cur_len; vec_idx++; offset = 0; } - if (vec_idx == uio->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(uio) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. @@ -330,18 +326,14 @@ skein_digest_final_uio(skein_ctx_t *ctx, crypto_data_t *digest, uio_t *uio = digest->cd_uio; /* we support only kernel buffer */ - if (uio->uio_segflg != UIO_SYSSPACE) + if (uio_segflg(uio) != UIO_SYSSPACE) return (CRYPTO_ARGUMENTS_BAD); /* * Jump to the first iovec containing ptr to the digest to be returned. */ - while (vec_idx < uio->uio_iovcnt && - offset >= uio->uio_iov[vec_idx].iov_len) { - offset -= uio->uio_iov[vec_idx].iov_len; - vec_idx++; - } - if (vec_idx == uio->uio_iovcnt) { + offset = uio_index_at_offset(uio, offset, &vec_idx); + if (vec_idx == uio_iovcnt(uio)) { /* * The caller specified an offset that is larger than the * total size of the buffers it provided. @@ -349,10 +341,10 @@ skein_digest_final_uio(skein_ctx_t *ctx, crypto_data_t *digest, return (CRYPTO_DATA_LEN_RANGE); } if (offset + CRYPTO_BITS2BYTES(ctx->sc_digest_bitlen) <= - uio->uio_iov[vec_idx].iov_len) { + uio_iovlen(uio, vec_idx)) { /* The computed digest will fit in the current iovec. */ SKEIN_OP(ctx, Final, - (uchar_t *)uio->uio_iov[vec_idx].iov_base + offset); + (uchar_t *)uio_iovbase(uio, vec_idx) + offset); } else { uint8_t *digest_tmp; off_t scratch_offset = 0; @@ -364,11 +356,11 @@ skein_digest_final_uio(skein_ctx_t *ctx, crypto_data_t *digest, if (digest_tmp == NULL) return (CRYPTO_HOST_MEMORY); SKEIN_OP(ctx, Final, digest_tmp); - while (vec_idx < uio->uio_iovcnt && length > 0) { - cur_len = MIN(uio->uio_iov[vec_idx].iov_len - offset, + while (vec_idx < uio_iovcnt(uio) && length > 0) { + cur_len = MIN(uio_iovlen(uio, vec_idx) - offset, length); bcopy(digest_tmp + scratch_offset, - uio->uio_iov[vec_idx].iov_base + offset, cur_len); + uio_iovbase(uio, vec_idx) + offset, cur_len); length -= cur_len; vec_idx++; @@ -377,7 +369,7 @@ skein_digest_final_uio(skein_ctx_t *ctx, crypto_data_t *digest, } kmem_free(digest_tmp, CRYPTO_BITS2BYTES(ctx->sc_digest_bitlen)); - if (vec_idx == uio->uio_iovcnt && length > 0) { + if (vec_idx == uio_iovcnt(uio) && length > 0) { /* * The end of the specified iovec's was reached but * the length requested could not be processed, i.e. diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c index a21ac8d74a4..3958a6f97a0 100644 --- a/module/zfs/dmu.c +++ b/module/zfs/dmu.c @@ -1327,7 +1327,7 @@ dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size) * NB: we could do this block-at-a-time, but it's nice * to be reading in parallel. */ - err = dmu_buf_hold_array_by_dnode(dn, uio->uio_loffset, size, + err = dmu_buf_hold_array_by_dnode(dn, uio_offset(uio), size, TRUE, FTAG, &numbufs, &dbp, 0); if (err) return (err); @@ -1339,7 +1339,7 @@ dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size) ASSERT(size > 0); - bufoff = uio->uio_loffset - db->db_offset; + bufoff = uio_offset(uio) - db->db_offset; tocpy = MIN(db->db_size - bufoff, size); #ifdef HAVE_UIO_ZEROCOPY @@ -1348,10 +1348,8 @@ dmu_read_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size) arc_buf_t *dbuf_abuf = dbi->db_buf; arc_buf_t *abuf = dbuf_loan_arcbuf(dbi); err = dmu_xuio_add(xuio, abuf, bufoff, tocpy); - if (!err) { - uio->uio_resid -= tocpy; - uio->uio_loffset += tocpy; - } + if (!err) + uio_advance(uio, tocpy); if (abuf == dbuf_abuf) XUIOSTAT_BUMP(xuiostat_rbuf_nocopy); @@ -1436,7 +1434,7 @@ dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx) int err = 0; int i; - err = dmu_buf_hold_array_by_dnode(dn, uio->uio_loffset, size, + err = dmu_buf_hold_array_by_dnode(dn, uio_offset(uio), size, FALSE, FTAG, &numbufs, &dbp, DMU_READ_PREFETCH); if (err) return (err); @@ -1448,7 +1446,7 @@ dmu_write_uio_dnode(dnode_t *dn, uio_t *uio, uint64_t size, dmu_tx_t *tx) ASSERT(size > 0); - bufoff = uio->uio_loffset - db->db_offset; + bufoff = uio_offset(uio) - db->db_offset; tocpy = MIN(db->db_size - bufoff, size); ASSERT(i == 0 || i == numbufs-1 || tocpy == db->db_size); diff --git a/module/zfs/sa.c b/module/zfs/sa.c index 557ab0949ca..ed531892e9b 100644 --- a/module/zfs/sa.c +++ b/module/zfs/sa.c @@ -1517,7 +1517,7 @@ sa_lookup_uio(sa_handle_t *hdl, sa_attr_type_t attr, uio_t *uio) mutex_enter(&hdl->sa_lock); if ((error = sa_attr_op(hdl, &bulk, 1, SA_LOOKUP, NULL)) == 0) { error = uiomove((void *)bulk.sa_addr, MIN(bulk.sa_size, - uio->uio_resid), UIO_READ, uio); + uio_resid(uio)), UIO_READ, uio); } mutex_exit(&hdl->sa_lock); return (error); diff --git a/module/zfs/zfs_sa.c b/module/zfs/zfs_sa.c index e20e92f1290..cbb773ffbdf 100644 --- a/module/zfs/zfs_sa.c +++ b/module/zfs/zfs_sa.c @@ -81,13 +81,13 @@ zfs_sa_readlink(znode_t *zp, uio_t *uio) if (bufsz + ZFS_OLD_ZNODE_PHYS_SIZE <= db->db_size) { error = uiomove((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE, - MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio); + MIN((size_t)bufsz, uio_resid(uio)), UIO_READ, uio); } else { dmu_buf_t *dbp; if ((error = dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) { error = uiomove(dbp->db_data, - MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio); + MIN((size_t)bufsz, uio_resid(uio)), UIO_READ, uio); dmu_buf_rele(dbp, FTAG); } }