Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upstream: Add convenience wrappers for common uio usage #10412

Merged
merged 1 commit into from
Jun 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
lundman marked this conversation as resolved.
Show resolved Hide resolved
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