Extending FreeBSD UIO Struct

In FreeBSD the struct uio was just a typedef to uio_t. In order to
extend this struct, outside of the definition for the struct uio, the
struct uio has been embedded inside of a uio_t struct.

Also renamed all the uio_* interfaces to be zfs_uio_* to make it clear
this is a ZFS interface.

Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Brian Atkinson <batkinson@lanl.gov>
Closes #11438
This commit is contained in:
Brian Atkinson
2021-01-20 22:27:30 -07:00
committed by Tony Hutter
parent cd4f9572d0
commit 0b1e6fcc3e
37 changed files with 521 additions and 457 deletions
+44 -35
View File
@@ -518,7 +518,7 @@ update_pages(znode_t *zp, int64_t start, int len, objset_t *os)
* in one single dmu_read() call.
*/
int
mappedread_sf(znode_t *zp, int nbytes, uio_t *uio)
mappedread_sf(znode_t *zp, int nbytes, zfs_uio_t *uio)
{
vnode_t *vp = ZTOV(zp);
objset_t *os = zp->z_zfsvfs->z_os;
@@ -530,14 +530,14 @@ mappedread_sf(znode_t *zp, int nbytes, uio_t *uio)
int len = nbytes;
int error = 0;
ASSERT(uio->uio_segflg == UIO_NOCOPY);
ASSERT(zfs_uio_segflg(uio) == UIO_NOCOPY);
ASSERT(vp->v_mount != NULL);
obj = vp->v_object;
ASSERT(obj != NULL);
ASSERT((uio->uio_loffset & PAGEOFFSET) == 0);
ASSERT((zfs_uio_offset(uio) & PAGEOFFSET) == 0);
zfs_vmobject_wlock_12(obj);
for (start = uio->uio_loffset; len > 0; start += PAGESIZE) {
for (start = zfs_uio_offset(uio); len > 0; start += PAGESIZE) {
int bytes = MIN(PAGESIZE, len);
pp = vm_page_grab_unlocked(obj, OFF_TO_IDX(start),
@@ -584,8 +584,7 @@ mappedread_sf(znode_t *zp, int nbytes, uio_t *uio)
}
if (error)
break;
uio->uio_resid -= bytes;
uio->uio_offset += bytes;
zfs_uio_advance(uio, bytes);
len -= bytes;
}
zfs_vmobject_wunlock_12(obj);
@@ -603,7 +602,7 @@ mappedread_sf(znode_t *zp, int nbytes, uio_t *uio)
* the file is memory mapped.
*/
int
mappedread(znode_t *zp, int nbytes, uio_t *uio)
mappedread(znode_t *zp, int nbytes, zfs_uio_t *uio)
{
vnode_t *vp = ZTOV(zp);
vm_object_t obj;
@@ -616,7 +615,7 @@ mappedread(znode_t *zp, int nbytes, uio_t *uio)
obj = vp->v_object;
ASSERT(obj != NULL);
start = uio->uio_loffset;
start = zfs_uio_offset(uio);
off = start & PAGEOFFSET;
zfs_vmobject_wlock_12(obj);
for (start &= PAGEMASK; len > 0; start += PAGESIZE) {
@@ -629,7 +628,8 @@ mappedread(znode_t *zp, int nbytes, uio_t *uio)
zfs_vmobject_wunlock_12(obj);
va = zfs_map_page(pp, &sf);
error = vn_io_fault_uiomove(va + off, bytes, uio);
error = vn_io_fault_uiomove(va + off, bytes,
GET_UIO_STRUCT(uio));
zfs_unmap_page(sf);
zfs_vmobject_wlock_12(obj);
page_unhold(pp);
@@ -1678,7 +1678,7 @@ zfs_rmdir(znode_t *dzp, const char *name, znode_t *cwd, cred_t *cr, int flags)
*/
/* ARGSUSED */
static int
zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
zfs_readdir(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, int *eofp,
int *ncookies, ulong_t **cookies)
{
znode_t *zp = VTOZ(vp);
@@ -1723,7 +1723,7 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
/*
* Check for valid iov_len.
*/
if (uio->uio_iov->iov_len <= 0) {
if (GET_UIO_STRUCT(uio)->uio_iov->iov_len <= 0) {
ZFS_EXIT(zfsvfs);
return (SET_ERROR(EINVAL));
}
@@ -1738,7 +1738,7 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
error = 0;
os = zfsvfs->z_os;
offset = uio->uio_loffset;
offset = zfs_uio_offset(uio);
prefetch = zp->z_zn_prefetch;
/*
@@ -1759,9 +1759,9 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
/*
* Get space to change directory entries into fs independent format.
*/
iovp = uio->uio_iov;
iovp = GET_UIO_STRUCT(uio)->uio_iov;
bytes_wanted = iovp->iov_len;
if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) {
if (zfs_uio_segflg(uio) != UIO_SYSSPACE || zfs_uio_iovcnt(uio) != 1) {
bufsize = bytes_wanted;
outbuf = kmem_alloc(bufsize, KM_SLEEP);
odp = (struct dirent64 *)outbuf;
@@ -1776,7 +1776,7 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
/*
* Minimum entry size is dirent size and 1 byte for a file name.
*/
ncooks = uio->uio_resid / (sizeof (struct dirent) -
ncooks = zfs_uio_resid(uio) / (sizeof (struct dirent) -
sizeof (((struct dirent *)NULL)->d_name) + 1);
cooks = malloc(ncooks * sizeof (ulong_t), M_TEMP, M_WAITOK);
*cookies = cooks;
@@ -1956,20 +1956,21 @@ zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
if (ncookies != NULL)
*ncookies -= ncooks;
if (uio->uio_segflg == UIO_SYSSPACE && uio->uio_iovcnt == 1) {
if (zfs_uio_segflg(uio) == UIO_SYSSPACE && zfs_uio_iovcnt(uio) == 1) {
iovp->iov_base += outcount;
iovp->iov_len -= outcount;
uio->uio_resid -= outcount;
} else if ((error = uiomove(outbuf, (long)outcount, UIO_READ, uio))) {
zfs_uio_resid(uio) -= outcount;
} else if ((error =
zfs_uiomove(outbuf, (long)outcount, UIO_READ, uio))) {
/*
* Reset the pointer.
*/
offset = uio->uio_loffset;
offset = zfs_uio_offset(uio);
}
update:
zap_cursor_fini(&zc);
if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
if (zfs_uio_segflg(uio) != UIO_SYSSPACE || zfs_uio_iovcnt(uio) != 1)
kmem_free(outbuf, bufsize);
if (error == ENOENT)
@@ -1977,7 +1978,7 @@ update:
ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
uio->uio_loffset = offset;
zfs_uio_setoffset(uio, offset);
ZFS_EXIT(zfsvfs);
if (error != 0 && cookies != NULL) {
free(*cookies, M_TEMP);
@@ -3660,7 +3661,7 @@ zfs_symlink(znode_t *dzp, const char *name, vattr_t *vap,
*/
/* ARGSUSED */
static int
zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct)
zfs_readlink(vnode_t *vp, zfs_uio_t *uio, cred_t *cr, caller_context_t *ct)
{
znode_t *zp = VTOZ(vp);
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
@@ -4443,8 +4444,9 @@ struct vop_read_args {
static int
zfs_freebsd_read(struct vop_read_args *ap)
{
return (zfs_read(VTOZ(ap->a_vp), ap->a_uio, ioflags(ap->a_ioflag),
zfs_uio_t uio;
zfs_uio_init(&uio, ap->a_uio);
return (zfs_read(VTOZ(ap->a_vp), &uio, ioflags(ap->a_ioflag),
ap->a_cred));
}
@@ -4460,8 +4462,9 @@ struct vop_write_args {
static int
zfs_freebsd_write(struct vop_write_args *ap)
{
return (zfs_write(VTOZ(ap->a_vp), ap->a_uio, ioflags(ap->a_ioflag),
zfs_uio_t uio;
zfs_uio_init(&uio, ap->a_uio);
return (zfs_write(VTOZ(ap->a_vp), &uio, ioflags(ap->a_ioflag),
ap->a_cred));
}
@@ -4713,8 +4716,9 @@ struct vop_readdir_args {
static int
zfs_freebsd_readdir(struct vop_readdir_args *ap)
{
return (zfs_readdir(ap->a_vp, ap->a_uio, ap->a_cred, ap->a_eofflag,
zfs_uio_t uio;
zfs_uio_init(&uio, ap->a_uio);
return (zfs_readdir(ap->a_vp, &uio, ap->a_cred, ap->a_eofflag,
ap->a_ncookies, ap->a_cookies));
}
@@ -5004,8 +5008,9 @@ struct vop_readlink_args {
static int
zfs_freebsd_readlink(struct vop_readlink_args *ap)
{
return (zfs_readlink(ap->a_vp, ap->a_uio, ap->a_cred, NULL));
zfs_uio_t uio;
zfs_uio_init(&uio, ap->a_uio);
return (zfs_readlink(ap->a_vp, &uio, ap->a_cred, NULL));
}
#ifndef _SYS_SYSPROTO_H_
@@ -5473,11 +5478,14 @@ zfs_listextattr(struct vop_listextattr_args *ap)
uint8_t dirbuf[sizeof (struct dirent)];
struct dirent *dp;
struct iovec aiov;
struct uio auio, *uio = ap->a_uio;
struct uio auio;
size_t *sizep = ap->a_size;
size_t plen;
vnode_t *xvp = NULL, *vp;
int done, error, eof, pos;
zfs_uio_t uio;
zfs_uio_init(&uio, ap->a_uio);
/*
* If the xattr property is off, refuse the request.
@@ -5559,15 +5567,16 @@ zfs_listextattr(struct vop_listextattr_args *ap)
nlen = dp->d_namlen - plen;
if (sizep != NULL)
*sizep += 1 + nlen;
else if (uio != NULL) {
else if (GET_UIO_STRUCT(&uio) != NULL) {
/*
* Format of extattr name entry is one byte for
* length and the rest for name.
*/
error = uiomove(&nlen, 1, uio->uio_rw, uio);
error = zfs_uiomove(&nlen, 1, zfs_uio_rw(&uio),
&uio);
if (error == 0) {
error = uiomove(dp->d_name + plen, nlen,
uio->uio_rw, uio);
error = zfs_uiomove(dp->d_name + plen,
nlen, zfs_uio_rw(&uio), &uio);
}
if (error != 0)
break;