Skip to content

Commit

Permalink
Add convenience wrappers for common uio usage
Browse files Browse the repository at this point in the history
The macOS uio struct is opaque and the API must be used, this
makes the smallest changes to the code for all platforms.

Reviewed-by: Matt Macy <[email protected]>
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Jorgen Lundman <[email protected]>
Closes openzfs#10412
  • Loading branch information
lundman authored and jsai20 committed Mar 30, 2021
1 parent 65d7315 commit fd2d2a1
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 250 deletions.
33 changes: 33 additions & 0 deletions include/os/freebsd/spl/sys/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
33 changes: 33 additions & 0 deletions include/os/linux/spl/sys/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
1 change: 0 additions & 1 deletion lib/libspl/include/os/freebsd/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
98 changes: 0 additions & 98 deletions lib/libspl/include/os/freebsd/sys/uio.h

This file was deleted.

1 change: 0 additions & 1 deletion lib/libspl/include/os/linux/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions lib/libspl/include/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,14 @@
#include <sys/types.h>
#include_next <sys/uio.h>

#ifdef __APPLE__
#include <sys/_types/_iovec_t.h>
#endif

#include <stdint.h>
typedef struct iovec iovec_t;

#if defined(__linux__) || defined(__APPLE__)
typedef enum uio_rw {
UIO_READ = 0,
UIO_WRITE = 1,
Expand All @@ -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;

Expand Down Expand Up @@ -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 */
30 changes: 14 additions & 16 deletions module/icp/algs/modes/modes.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
Loading

0 comments on commit fd2d2a1

Please sign in to comment.