diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2012-03-01 03:53:07 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2012-03-01 03:53:07 +0000 |
commit | 2d142012e7cfd4cd61593c97673bac8cc3709f1d (patch) | |
tree | fe54465a7586f88b20815ce4611bbe757bbdc610 /sys/nfsclient | |
parent | 4b408c2addcd1440e42b8c3a51da7d32ae672f24 (diff) | |
download | FreeBSD-src-2d142012e7cfd4cd61593c97673bac8cc3709f1d.zip FreeBSD-src-2d142012e7cfd4cd61593c97673bac8cc3709f1d.tar.gz |
Fix the NFS clients so that they use copyin() instead of bcopy(),
when doing direct I/O. This direct I/O code is not enabled by default.
Submitted by: kib (earlier version)
Reviewed by: kib
MFC after: 1 week
Diffstat (limited to 'sys/nfsclient')
-rw-r--r-- | sys/nfsclient/nfs_bio.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 4a90ad7..e005fc8 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -814,7 +814,21 @@ do_sync: t_uio->uio_segflg = UIO_SYSSPACE; t_uio->uio_rw = UIO_WRITE; t_uio->uio_td = td; - bcopy(uiop->uio_iov->iov_base, t_iov->iov_base, size); + KASSERT(uiop->uio_segflg == UIO_USERSPACE || + uiop->uio_segflg == UIO_SYSSPACE, + ("nfs_directio_write: Bad uio_segflg")); + if (uiop->uio_segflg == UIO_USERSPACE) { + error = copyin(uiop->uio_iov->iov_base, + t_iov->iov_base, size); + if (error != 0) + goto err_free; + } else + /* + * UIO_SYSSPACE may never happen, but handle + * it just in case it does. + */ + bcopy(uiop->uio_iov->iov_base, t_iov->iov_base, + size); bp->b_flags |= B_DIRECT; bp->b_iocmd = BIO_WRITE; if (cred != NOCRED) { @@ -825,6 +839,7 @@ do_sync: bp->b_caller1 = (void *)t_uio; bp->b_vp = vp; error = nfs_asyncio(nmp, bp, NOCRED, td); +err_free: if (error) { free(t_iov->iov_base, M_NFSDIRECTIO); free(t_iov, M_NFSDIRECTIO); |