#include <asm/uaccess.h>
#include <sys/types.h>
+#if defined(HAVE_VFS_IOV_ITER) && defined(HAVE_FAULT_IN_IOV_ITER_READABLE)
+#define iov_iter_fault_in_readable(a, b) fault_in_iov_iter_readable(a, b)
+#endif
+
typedef struct iovec iovec_t;
-typedef enum uio_rw {
+typedef enum zfs_uio_rw {
UIO_READ = 0,
UIO_WRITE = 1,
-} uio_rw_t;
+} zfs_uio_rw_t;
-typedef enum uio_seg {
+typedef enum zfs_uio_seg {
UIO_USERSPACE = 0,
UIO_SYSSPACE = 1,
- UIO_USERISPACE = 2,
- UIO_BVEC = 3,
-} uio_seg_t;
+ UIO_BVEC = 2,
+#if defined(HAVE_VFS_IOV_ITER)
+ UIO_ITER = 3,
+#endif
+} zfs_uio_seg_t;
-typedef struct uio {
+typedef struct zfs_uio {
union {
const struct iovec *uio_iov;
const struct bio_vec *uio_bvec;
+#if defined(HAVE_VFS_IOV_ITER)
+ struct iov_iter *uio_iter;
+#endif
};
int uio_iovcnt;
offset_t uio_loffset;
- uio_seg_t uio_segflg;
+ zfs_uio_seg_t uio_segflg;
boolean_t uio_fault_disable;
uint16_t uio_fmode;
uint16_t uio_extflg;
- offset_t uio_limit;
ssize_t uio_resid;
- size_t uio_skip;
-} uio_t;
-typedef struct aio_req {
- uio_t *aio_uio;
- void *aio_private;
-} aio_req_t;
-
-typedef enum xuio_type {
- UIOTYPE_ASYNCIO,
- UIOTYPE_ZEROCOPY,
-} xuio_type_t;
+ size_t uio_skip;
+ struct request *rq;
+} zfs_uio_t;
-#define UIOA_IOV_MAX 16
-typedef struct uioa_page_s {
- int uioa_pfncnt;
- void **uioa_ppp;
- caddr_t uioa_base;
- size_t uioa_len;
-} uioa_page_t;
+#define zfs_uio_segflg(u) (u)->uio_segflg
+#define zfs_uio_offset(u) (u)->uio_loffset
+#define zfs_uio_resid(u) (u)->uio_resid
+#define zfs_uio_iovcnt(u) (u)->uio_iovcnt
+#define zfs_uio_iovlen(u, idx) (u)->uio_iov[(idx)].iov_len
+#define zfs_uio_iovbase(u, idx) (u)->uio_iov[(idx)].iov_base
+#define zfs_uio_fault_disable(u, set) (u)->uio_fault_disable = set
+#define zfs_uio_rlimit_fsize(z, u) (0)
+#define zfs_uio_fault_move(p, n, rw, u) zfs_uiomove((p), (n), (rw), (u))
-typedef struct xuio {
- uio_t xu_uio;
- enum xuio_type xu_type;
- union {
- struct {
- uint32_t xu_a_state;
- ssize_t xu_a_mbytes;
- uioa_page_t *xu_a_lcur;
- void **xu_a_lppp;
- void *xu_a_hwst[4];
- uioa_page_t xu_a_locked[UIOA_IOV_MAX];
- } xu_aio;
-
- struct {
- int xu_zc_rw;
- void *xu_zc_priv;
- } xu_zc;
- } xu_ext;
-} xuio_t;
-
-#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
+extern int zfs_uio_prefaultpages(ssize_t, zfs_uio_t *);
static inline void
-uio_iov_at_index(uio_t *uio, uint_t idx, void **base, uint64_t *len)
+zfs_uio_setoffset(zfs_uio_t *uio, offset_t off)
{
- *base = uio_iovbase(uio, idx);
- *len = uio_iovlen(uio, idx);
+ uio->uio_loffset = off;
}
static inline void
-uio_advance(uio_t *uio, size_t size)
+zfs_uio_advance(zfs_uio_t *uio, ssize_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)
+static inline void
+zfs_uio_iovec_init(zfs_uio_t *uio, const struct iovec *iov,
+ unsigned long nr_segs, offset_t offset, zfs_uio_seg_t seg, ssize_t resid,
+ size_t skip)
+{
+ ASSERT(seg == UIO_USERSPACE || seg == UIO_SYSSPACE);
+
+ uio->uio_iov = iov;
+ uio->uio_iovcnt = nr_segs;
+ uio->uio_loffset = offset;
+ uio->uio_segflg = seg;
+ uio->uio_fault_disable = B_FALSE;
+ uio->uio_fmode = 0;
+ uio->uio_extflg = 0;
+ uio->uio_resid = resid;
+ uio->uio_skip = skip;
+}
+
+static inline void
+zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq)
{
- *vec_idx = 0;
- while (*vec_idx < uio_iovcnt(uio) && off >= uio_iovlen(uio, *vec_idx)) {
- off -= uio_iovlen(uio, *vec_idx);
- (*vec_idx)++;
+ /* Either bio or rq will be set, but not both */
+ ASSERT3P(uio, !=, bio);
+
+ if (bio) {
+ uio->uio_iovcnt = bio->bi_vcnt - BIO_BI_IDX(bio);
+ uio->uio_bvec = &bio->bi_io_vec[BIO_BI_IDX(bio)];
+ } else {
+ uio->uio_bvec = NULL;
+ uio->uio_iovcnt = 0;
+ }
+
+ uio->uio_loffset = io_offset(bio, rq);
+ uio->uio_segflg = UIO_BVEC;
+ uio->uio_fault_disable = B_FALSE;
+ uio->uio_fmode = 0;
+ uio->uio_extflg = 0;
+ uio->uio_resid = io_size(bio, rq);
+ if (bio) {
+ uio->uio_skip = BIO_BI_SKIP(bio);
+ } else {
+ uio->uio_skip = 0;
}
- return (off);
+ uio->rq = rq;
+}
+
+#if defined(HAVE_VFS_IOV_ITER)
+static inline void
+zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
+ ssize_t resid, size_t skip)
+{
+ uio->uio_iter = iter;
+ uio->uio_iovcnt = iter->nr_segs;
+ uio->uio_loffset = offset;
+ uio->uio_segflg = UIO_ITER;
+ uio->uio_fault_disable = B_FALSE;
+ uio->uio_fmode = 0;
+ uio->uio_extflg = 0;
+ uio->uio_resid = resid;
+ uio->uio_skip = skip;
}
+#endif
+
+#if defined(HAVE_ITER_IOV)
+#define zfs_uio_iter_iov(iter) iter_iov((iter))
+#else
+#define zfs_uio_iter_iov(iter) (iter)->iov
+#endif
+
+#if defined(HAVE_IOV_ITER_TYPE)
+#define zfs_uio_iov_iter_type(iter) iov_iter_type((iter))
+#else
+#define zfs_uio_iov_iter_type(iter) (iter)->type
+#endif
#endif /* SPL_UIO_H */