From owner-svn-src-all@freebsd.org Tue Nov 21 18:01:45 2017 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 15A34DF5606; Tue, 21 Nov 2017 18:01:45 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E15BD784DD; Tue, 21 Nov 2017 18:01:44 +0000 (UTC) (envelope-from avg@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id vALI1hh7095026; Tue, 21 Nov 2017 18:01:43 GMT (envelope-from avg@FreeBSD.org) Received: (from avg@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id vALI1hDq095025; Tue, 21 Nov 2017 18:01:43 GMT (envelope-from avg@FreeBSD.org) Message-Id: <201711211801.vALI1hDq095025@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: avg set sender to avg@FreeBSD.org using -f From: Andriy Gapon Date: Tue, 21 Nov 2017 18:01:43 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r326067 - head/sys/cddl/compat/opensolaris/kern X-SVN-Group: head X-SVN-Commit-Author: avg X-SVN-Commit-Paths: head/sys/cddl/compat/opensolaris/kern X-SVN-Commit-Revision: 326067 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Nov 2017 18:01:45 -0000 Author: avg Date: Tue Nov 21 18:01:43 2017 New Revision: 326067 URL: https://svnweb.freebsd.org/changeset/base/326067 Log: make illumos uiocopy use vn_io_fault_uiomove uiocopy() is currently unused, its purpose is copy data from a uio without modifying the uio. It was in use before the vn_io_fault support was added to ZFS, at which point our code diverged from the illumos code a little bit. Because ZFS is the only (potential) user of the function we are free to modify it to better suit ZFS needs. The intention behind this change is to remove the differences introduced earlier in zfs_write(). While here, re-implement uioskip() using uiomove() with uio_segflg == UIO_NOCOPY. The story of uioskip is the same as with uiocopy. Reviewed by: mav MFC after: 1 week Modified: head/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c Modified: head/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c ============================================================================== --- head/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c Tue Nov 21 17:23:16 2017 (r326066) +++ head/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c Tue Nov 21 18:01:43 2017 (r326067) @@ -42,6 +42,7 @@ #include #include +#include /* * same as uiomove() but doesn't modify uio structure. @@ -50,63 +51,42 @@ int uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes) { - struct iovec *iov; - ulong_t cnt; - int error, iovcnt; + struct iovec small_iovec[1]; + struct uio small_uio_clone; + struct uio *uio_clone; + int error; - iovcnt = uio->uio_iovcnt; - *cbytes = 0; - - for (iov = uio->uio_iov; n > 0 && iovcnt > 0; iov++, iovcnt--) { - cnt = MIN(iov->iov_len, n); - if (cnt == 0) - continue; - - switch (uio->uio_segflg) { - case UIO_USERSPACE: - if (rw == UIO_READ) - error = copyout(p, iov->iov_base, cnt); - else - error = copyin(iov->iov_base, p, cnt); - if (error) - return (error); - break; - case UIO_SYSSPACE: - if (uio->uio_rw == UIO_READ) - bcopy(p, iov->iov_base, cnt); - else - bcopy(iov->iov_base, p, cnt); - break; - } - - p = (caddr_t)p + cnt; - n -= cnt; - *cbytes += cnt; + ASSERT3U(uio->uio_rw, ==, rw); + if (uio->uio_iovcnt == 1) { + small_uio_clone = *uio; + small_iovec[0] = *uio->uio_iov; + small_uio_clone.uio_iov = small_iovec; + uio_clone = &small_uio_clone; + } else { + uio_clone = cloneuio(uio); } - return (0); + + error = vn_io_fault_uiomove(p, n, uio_clone); + *cbytes = uio->uio_resid - uio_clone->uio_resid; + if (uio_clone != &small_uio_clone) + free(uio_clone, M_IOV); + return (error); } /* * Drop the next n chars out of *uiop. */ void -uioskip(uio_t *uiop, size_t n) +uioskip(uio_t *uio, size_t n) { - if (n > uiop->uio_resid) + enum uio_seg segflg; + + /* For the full compatibility with illumos. */ + if (n > uio->uio_resid) return; - while (n != 0) { - register iovec_t *iovp = uiop->uio_iov; - register size_t niovb = MIN(iovp->iov_len, n); - if (niovb == 0) { - uiop->uio_iov++; - uiop->uio_iovcnt--; - continue; - } - iovp->iov_base += niovb; - uiop->uio_loffset += niovb; - iovp->iov_len -= niovb; - uiop->uio_resid -= niovb; - n -= niovb; - } + segflg = uio->uio_segflg; + uio->uio_segflg = UIO_NOCOPY; + uiomove(NULL, n, uio->uio_rw, uio); + uio->uio_segflg = segflg; }